2011-09-28 185 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),以及 产生,其中包括它(和其他任何这 是必要的虚拟源文件)。