2013-06-04 102 views
0
struct ABC {}; 

template<typename T> 
class DEF 
{ 
    void f0(typename T::ab) {} //ERROR 
    void f1() {typename T::ab var;} //Fine 
}; 

DEF<ABC> obj; 

我想如果我不使用類模板的特定成員函數,它永遠不會被編譯器構造。因此,即使f1()與預期的代碼編譯罰款,因爲obj從來沒有使用它。爲什麼f0()的存在會導致編譯錯誤?我也沒有使用它。爲什麼在這種情況下構造類模板的成員函數?

{MinGW的克++ 4.7.2,視窗7}

+0

編譯器錯誤說什麼? –

+0

錯誤:在'struct ABC'中沒有類型命名爲'ab' – ustulation

回答

4

每個成員函數聲明是整個類定義的組成部分。同時,成員函數定義是一個完全獨立的實體,它不是類定義的一部分。

當你實例化某個特定模板類的對象時,你正在實例化該類的整個定義,即你正在「使用」該類的整個定義,這反過來意味着你正在「使用」所有成員聲明也是如此。

下面是變成類定義在你的情況下,一旦模板是專門部分

template<typename T> 
class DEF 
{ 
    void f0(typename T::ab); 
    void f1(); 
}; 

上述所有已到有效期爲T給定值,以便類定義爲可用,即爲了能夠聲明DEF<ABC> obj;

同時的

template<typename T> void DEF<T>::f1() 
{ 
    typename T::ab var; 
} 

的定義是一個獨立的模板。它僅在使用f1時被實例化。

+2

ok。我已經引用了這部分標準,這似乎解釋了你所說的全部內容: 報價14.7.2 '類模板特化的隱式實例化導致聲明的隱式實例化,但不是定義或類成員函數「 – ustulation

2

編譯器至少需要爲函數來確定,然後,如果它被使用(並且隨後編譯體或不)有效的原型。

2

這是因爲懶惰的實例。當你做DEF<ABC> obj。編譯器將查看類DEF的原型/定義。因此void f0(typename T::ab)失敗,因爲ab不存在,你會得到一個編譯錯誤。

你沒有得到編譯器錯誤的原因是void f1(){typename T::ab var}是因爲它從未被實例化過。如果你做的是obj.f1(),你會發現它會將與DEF :: f0相關的信息錯誤地輸出。

相關問題