如何协调将头/源与模板分离的C++习惯用法?

Max*_*Max 21 c++ templates header

我想知道这个模板业务.

在C和C++中,将声明放在源文件中的头文件和定义中是很常见的,并将两者完全分开.然而,在模板方面,这似乎不可能(以任何好的方式),而且众所周知,模板是一个很好的工具.

此外,Boost主要是标题,所以这是一个真正的问题.在C++中分离标题和源代码仍然是一个好主意,还是我不应该非常依赖模板?

Coi*_*oin 19

在编译时实例化模板的成本很高,但在运行时非常自由.基本上,每次使用新模板类型时,编译器都必须为该新类型生成代码,这就是代码在头中的原因,以便编译器可以在以后访问代码.

将所有代码放在.cpp中,编译器只需编译一次代码就可以大大加快编译速度.理论上你可以在头文件中编写所有代码,它可以正常工作,但编译非常大的项目需要花费很长时间.此外,只要您在任何地方更改一行,您就必须重建所有内容.

现在你可能会问,为什么STL和BOOST不是那么慢?这就是预编译头文件拯救的地方.PCH让编译器只进行一次最昂贵的工作.这适用于不会像库一样经常更改的代码,但是对于经常更改的代码,它的效果完全无效,因为您每次都必须重新编译整组预编译头文件.编译器还使用了一些技巧来避免重新编译每个编译单元中的所有模板代码.

另请注意,C++ 0x将引入显式机制来更好地控制模板实例化.您将能够显式实例化模板,最重要的是,可以防止某些编译单元中的实例化.但是,大部分工作已由大多数编译器在我们不知情的情况下完成.

因此,经验法则是,在.cpp中尽可能多地放置代码(并包含指令).如果你不能,那么,你不能.

我的建议是:不要仅仅为了它的模板.如果你必须模板,要小心并注意你实际上在模板将带来的编译速度和可用性之间进行选择.


Let*_*_Be 7

我个人最喜欢的是这种结构:

头文件:

#ifndef HEADER_FILE
#define HEADER_FILE

template < typename T > 
class X { void method(); };

#include "header_impl.h"

#endif
Run Code Online (Sandbox Code Playgroud)

实施文件:

#ifndef HEADER_IMPL_FILE
#define HEADER_IMPL_FILE

#include "header.h"

template < typename T > 
void X<T>::method() { }

#endif
Run Code Online (Sandbox Code Playgroud)

  • -1虽然它可能是由于某种原因,你最喜欢的,但是如果没有说明它的优点是什么,以及如何解决在使用模板之前不知道T的情况,那么这些信息就不是很有用了.(在impl上有if-guard,暗示你将impl包含在某个地方,虽然你没有这么说,并且有两个包含的文件与拥有更大的头文件非常相似) (3认同)