2011-11-02 29 views
6

你好,祝你有美好的一天。C++:強制完成模板編譯(MSVC/G ++)

下面的代碼片段在編譯的cl.exe(15.00.30729.01)和MinGW-G ++(4.4.0):

template<typename T> class Test{ 
public: 
    T t; 
    void error(){ 
     int doesNotExist = 6; 
     return doesNotExist;//<---- void function returning result 
    } 
}; 

int main(int argc, char** argv){ 
    Test<int> test; 
    return 0; 
} 

此外,在cl.exe時你甚至可以像這樣脫身:

template<typename T> class Test{ 
public: 
    T t; 
    void error(){ 
     doesNotExist = 6;//<---- undeclared variable 
     return doesNotExist;//<---- void function returning result 
    } 
}; 

現在,這顯然發生,因爲編譯器不會創建模板類的方法的內容,直到有人調用它們。但是,當您設計大型模板類時,這可能會造成問題(因爲您很可能忘記將測試調用添加到新方法的某處)。

的問題是:
是否有g的編譯器開關++或cl.exe時,這將迫使編譯器來處理整個模板(因此,此代碼片段將觸發編譯錯誤)?

回答

11

如果你想與幾個類型的測試模板,您可以觸發類型的手動實例,如:類模板

// at namespace level 
template class Test<int>; 

顯式實例自動觸發所有成員的實例,其似乎是你想要的。

實際的問題是,該語言旨在明確允許您想避免的行爲。當一個類模板被隱式實例化時,編譯器將只實例化那些使用的方法。該特性的主要用例是某些方法可能對實例化類型施加比其他方法更嚴格的要求,如果所有方法都實例化了總是那麼類模板只能用於那些滿足更嚴格要求的類型。

通過允許編譯器僅實例化那些使用的方法,類模板可以與不滿足所有方法的所有要求的類型一起使用,只要它們滿足方法的要求這是實際使用的。

一個常見的例子是在std::map<>operator[]需要的value_type默認constructibleoperator[]將創建一個新對象缺省初始化如果該鍵不存在在容器中,並返回對它的引用)。只要您不使用operator[](或任何其他強制實施該要求的成員函數),該語言的行爲允許您在不是默認構造的的類型上使用std::map

+2

是的,顯式模板實例化是你想要的。另請參閱:http://msdn.microsoft.com/en-us/library/by56e477%28VS.80%29.aspx –

+0

對於沒有編譯器錯誤的實際目的很好的解釋。 – iammilind

+0

好的,它的工作原理。我接受你的回答,但沒有必要解釋爲什麼這種方式有效(我已經知道)。謝謝回覆。 – SigTerm