2012-06-12 28 views
3

我想創建一個模板類(我們稱之爲Foo),它只接受一些特定的類型參數(假設只有doublefloat)。通常,模板在頭文件(.h)中實現,因爲未知如何在用戶代碼中實例化它。在這種情況下,它更有意義落實在實現文件(.cpp)類,像這樣:如何在C++中爲實例化的模板類編寫頭文件?

// Foo.cpp: 

template <class T> 
class Foo 
{ 
    // Insert members here 
}; 

typedef Foo<double> Foo_d; 
typedef Foo<float> Foo_f; 

這將實例化和編譯類時Foo.cpp中進行編譯。但是,那麼我如何在頭文件中聲明它,而不用另外編寫Foo_dFoo_f的聲明?

+0

這不能回答你的問題,但是命名一個擴展名爲「.c」的C++源文件是個不好的做法。 – 2012-06-12 00:30:06

+0

可能是以下副本:http://stackoverflow.com/questions/874298/c-templates-that-accept-only-certain-types此問題顯示如何僅允許輸入某些類型,以便您不要不必自己聲明它們,如果用戶嘗試的東西不是你所允許的,它只會拋出一個錯誤。 – tpg2114

+0

@Michael這是評論中的一個愚蠢的錯誤。 – Matt

回答

5

您可以在頭文件中定義模板,聲明方法但不定義它們。例如:

template <typename T> 
class Foo { 
    T val; 
public: 
    Foo (T t); 
    T value(); 
}; 

typedef Foo<double> Foo_d; 
typedef Foo<float> Foo_f; 

.cpp文件,你完成的方法的實現,然後實例所需的模板。

#include "foo_template.hpp" 

template <typename T> 
Foo<T>::Foo (T t) : val(t) {} 

template <typename T> 
T Foo<T>::value() { return val; } 

template class Foo<double>; 
template class Foo<float>; 

目標文件應該有實例從明確實例化模板FooFoo_dFoo_f。用於模板Foo的任何其他類型都將導致鏈接錯誤,因爲它們的實例化將不存在。或者,更迂迴地說,編譯器像平常一樣按需創建實例,但它不能解析與類方法相對應的符號,因爲這些實例不會存在。

4

除非我弄錯了,否則您所描述的正是新C++ 11 extern template功能的用例。要使用此功能,您需要將模板類的接口放在頭文件中。然後您將結束以下行的頭文件:

extern template class Foo<float>; 
extern template class Foo<double>; 

這告訴任何包含頭文件的文件在使用時不嘗試實例化模板。然後,在你的C++文件,那麼您需要實現模板類,然後將與線

template class Foo<float>; 
template class Foo<double>; 

這最後兩行強制編譯器實例化模板在這個翻譯單位結束,這樣你就不會得到任何鏈接錯誤。

希望這會有所幫助!

+0

謝謝,但有沒有'C++ 11'做到這一點? – Matt

+1

@ Matt-這就是(現在不推薦使用的)'export'關鍵字應該做的事情。這個確切的問題是首先引入'extern template'的原因之一,我不認爲有一個解決方法。 – templatetypedef

+0

哦。你應該添加到你的答案。 – Matt