具体来说,请注意此报价
一个常见的解决方案是在头文件中编写模板声明,然后在实现文件( 例如 .tpp )中实现类,并在头文件的末尾包含这个实现文件。
我将我最感兴趣的部分加粗。
.tpp 文件有什么意义?我尝试完全按照该页面中的建议进行操作,并且成功了。但后来,我将文件扩展名更改为任何随机乱码(如 .zz 或 .ypp),它仍然有效!它应该工作吗?它是 .tpp 还是任何其他扩展名是否重要?为什么不使用.cpp?
这是我感到困惑的另一件事。
如果我的实现是用 .cpp 编写的,并且头文件定义了非模板函数,那么我只需要编译 .cpp 文件一次,对吗?至少在我更改 .cpp 文件中的某些内容之前。
但是,如果我有一个定义模板函数的标头,并且我的实现在一个带有随机时髦扩展名的文件中,它是如何编译的? 每次 我编译任何源代码 #include
s 所说的标题时,是否都会编译实现?
原文由 Manuel 发布,翻译遵循 CC BY-SA 4.0 许可协议
扩展名是什么并不重要,但不要使用
.cpp
因为它违反约定(它仍然可以工作,但不要这样做;.cpp
文件通常是源文件)。除此之外,这取决于您的代码库使用什么。例如,我(和 Boost 代码库)为此目的使用.ipp
。当您不希望包含模块接口的文件包含所有血腥的实现细节时使用它。但是您不能在
.cpp
文件中编写实现,因为它是一个模板。所以你尽你所能(不考虑显式实例化等)。例如东西.hpp
东西.ipp
您不能将通用模板代码拆分为实现文件。您需要完整的代码可见才能使用模板,这就是为什么您需要将所有内容放在头文件中的原因。更多见 为什么模板只能在头文件中实现?
您不编译
.tpp
,.ipp
,-inl.h
等文件。它们就像头文件一样,只是它们只包含在其他头文件中。您只编译源 (.cpp
,.cc
) 文件。