2014-02-20 91 views
2

我有兩個具有靜態成員實例的類的測試用例。第一種使用非模板化樣本,第二種依賴於通用對象類型。未被調用的C++模板靜態成員構造函數

的困境是簡單:靜態成員的構造函數main函數之前被調用(因爲它應該),但只適用於特定對象類型。泛型類型不表現出相同的行爲。事實上,構造函數根本沒有編譯。似乎編譯器決定完全忽略它作爲(不完全合理)優化的手段。

我想知道發生了什麼,並且可以做些什麼來使它以最優雅的方式工作。我認爲明顯的答案是:在代碼中的某處使用該靜態成員。我不希望這樣做,因爲特定類型的案例不使用該靜態成員,除了在其構造函數中執行某些「工作」之外。

的代碼示例:

////////////////////////////////////////////// 
// Specific case 
////////////////////////////////////////////// 
class CPassive 
{ 
public: 
    CPassive() 
    { 
     printf(" passively called "); 
    } 
}; 

class CActive 
{ 
private: 
    static CPassive ms_passive; 
}; 
CPassive CActive::ms_passive; 
/////////////////////////////////////////////////////////// 
// GENERIC TYPES 
/////////////////////////////////////////////////////////// 
class CSample 
{ 
public: 
    CSample() 
    { 
     printf("sample "); 
    } 
}; 

template <typename T> 
class CGenericPassive 
{ 
public: 
    CGenericPassive() 
    { 
     T sample; 
     printf(" generic passive .. "); 
    } 
private: 
}; 

template <typename T> 
class CGenericActive 
{ 
private: 
    static CGenericPassive<T> ms_passive; 
}; 
template<typename T> 
CGenericPassive<T> CGenericActive<T>::ms_passive; 

int main(int argc, char** argv) 
{ 
    CActive activeExample;// instantiates the static member 
    CGenericActive<CSample> activeExample; // obliterates the static from the class def. 
} 
+0

我想我不完全理解。對於泛型類型,您希望運行多少個版本的類,以及爲什麼期望這些版本運行而不是無限數量? 例如, 'CGenericPassive CGenericActive :: ms_passive;'和'CGenericPassive​​CGenericActive​​:: ms_passive;' 而你是什麼意思的 「抹殺從類靜態的」? – m24p

+0

什麼問題?這段代碼是不是在做你的想法?這是什麼代碼輸出?更具體地說,這個代碼是做什麼的,你需要調整你的教育? – Dan

+0

@Dan模板化的靜態成員必須在非模板化函數中明確引用,以便實例化,而常規靜態成員不需要。我得到了一個答案poi.ting了這一點,但它感覺hackish或似乎有一個C++的規則怪癖。 – teodron

回答

3

要實例化的需要從非模板代碼引用的每個類模板中的每一個(非虛擬)構件,直接或間接地。實例化類本身是不夠的。

這是通過標準的14.7.1/2決定:

除非類模板或成員模板的成員已明確實例化或明確專門的,該成員的專業化隱式實例化時專業化是在需要成員定義存在的上下文中引用的;特別是靜態數據成員的初始化(以及任何相關的副作用)不會發生,除非靜態數據成員本身以需要靜態數據成員定義存在的方式使用。

在你的情況下,它也足以從CGenericActive構造函數引用成員(你需要寫顯然這個構造),像這樣:

CGenericActive() 
{ 
    // just reference it so it gets instantiated 
    (void)ms_passive; 
} 

Full live example

+0

謝謝!這也是我嘗試過的一種解決方法,但它感覺很駭人。我想我必須將更多的邏輯委託給靜態成員,以便它更透明可靠地工作,以免混淆第三方程序員。順便說一句:有沒有任何C++規則來決定這種行爲?與模板化代碼相同:如果沒有在任何地方使用,它不會(顯然)生成和編譯? (因爲,直觀地看來,即使成員的類構造函數正在做一些不應該優化的工作)。 – teodron

+1

增加了對標準章節和詩句的引用。 –