2011-09-28 234 views
6

我讀舊的數據結構的書,它說,當你在做模板類節目應該包括.h文件的末尾的.cpp結束的.cpp。包括模板頭文件

據我知道你需要做的全功能的實現在任何模板類成員函數的.h文件中 - 這是由於這樣的模板編譯工作。

我學會了可以放在一個實現文件的模板類的唯一功能是模板專業化的功能即:template<> Class<Type>::function_name()

爲什麼這本書建議包括在.H結束在.cpp?這只是將實現分離到不同文件中的一種方式,同時讓它們與頭文件一起編譯?如果是的話,你會在哪裏投入真正的專業化 - 我猜他們無法進入包含頭文件的.cpp文件。

回答

9

最有可能的作者傾向於具有不同的文件中聲明和定義,我可以猜測這是因爲它可以更容易地聲明和定義之間跳轉。

但是「cpp」文件擴展名有點混亂。通常這些文件被稱爲「ipp」用於「Inline C++」。

+2

我從未在我的生活中看到過這些名爲'ipp'的文件。 –

+0

@JohnDibling:它全部都是提升。之前甚至在SO上提出了有關這方面的問題。 – 2011-09-28 14:02:25

+0

請參閱http://stackoverflow.com/questions/543507/in-the-c-boost-libraries-why-is-there-a-ipp-extension-on-some-header-files –

3

這可能是舊的說法,我認爲你的實施和申報分離的分析是正確的。當寫這本書時,作者可能會想到一個cpp文件作爲定義所在的文件,而h文件則是作爲聲明所在的文件。自然,由於重複的定義,將實際明確的專業化放入前一個文件中對鏈接器來說自然是致命的(或至少是無用的)。現在,我會避免命名定義文件.cpp。

0

據我知道你需要做的全功能的實現在任何模板類成員函數你 .h文件中 - 這是由於方式 模板編譯工作。

可能是本書假設您在.cpp文件中具有全功能實現。

如果cpp文件中有完整的專業化版本,則不應將其包含在頭文件中。如果你這樣做,它很可能不會編譯。因爲編譯器會看到與頭文件相同的函數的多個定義,通常會包含在多個源文件中。

0

如果要使用模板,則必須在實例化模板的TU中可見整個模板定義。所以你可以簡單地把完整的定義放在頭文件中。

只有當你真的想要保持類定義和類成員函數體單獨,那麼你可能會試圖將這些函數定義放入一個單獨的文件中。但是,上述規則仍然適用,因此您必須將單獨的文件與標題一起包含,以便任何人都能夠使用該模板。

這是一個味道的問題。如果成員函數體很短,你可以將它們定義爲內聯。還要記住,在類定義中定義的函數被隱式聲明爲inline,而如果單獨編寫這些主體,則必須明確指定該函數。

部分專業化的模板仍然是一個模板,因此應用相同的規則。

一個完全專業類模板只是一個普通的類,所以你對待是這樣的:

// FooInt.hpp 
template <typename> class Foo; 
template <> class Foo<int> 
{ 
    // your class here 
}; 

有一件事你可能已經在心中「顯式模板實例化」,一拉template class Foo<int>;。那是別的;如果你有興趣使用它,留下評論。

1

首先,有沒有規則,你必須擁有的 模板實現在.h(或.hpp,或.hh)文件;事實上,對於任何東西 但最簡單的模板,我會建議不要這樣做。你做 必須包括執行,不管文件。作者可能想到的是將該實現放在一個文件中,幷包含該文件。我建議你找一個不同的名字, 然而,因爲大多數人(和一些IDE)會假設你應該編譯所有的.cpp文件。其中.cc.hh爲 的常見約定是針對模板 實現的源和標頭的常用擴展名是.tcc;在Windows世界(其中.cpp幾乎是通用的), 我會推薦類似.tpp

請注意,模板的最早實現需要 實現爲.cpp。然而,這些實現不需要 (或允許)將其包括在內;編譯器搜索與其中 模板類定義或函數聲明出現在.hpp(或.hh)文件 .cpp(或.cc),以及 產生,其中包括它(和其他任何這 是必要的虛擬源文件)。