c ++模板和头文件

kam*_*lot 27 c++ templates header file

所以,我听说C++模板不应该分为标题(.h)和源(.cpp)文件.

例如,像这样的模板:

template <class T>
class J
{   
   T something;
};
Run Code Online (Sandbox Code Playgroud)

这是真的?为什么会这样?

如果因为这个我必须将声明和实现放在同一个文件中,我应该把它放在.h文件或.cpp文件中吗?

Lig*_*ica 27

头.

这是因为模板在编​​译时被实例化,而不是链接时,并且不同的翻译单元(大致相当于您的.cpp文件)仅在链接时"彼此了解".标题往往在编译时被广泛"了解",因为#include它们在任何需要它们的翻译单元中.

阅读https://isocpp.org/wiki/faq/templates了解更多信息.


Chr*_* A. 14

你不能将模板化的类放入.cpp文件的原因是因为为了"编译".cpp文件,你需要知道正在使用的类型是什么代替T.因为它是一个模板化的类(像你的类J)没有足够的信息来编译.因此它必须全部在标题中.

如果您希望将实现分解为另一个文件以保持清洁,最佳做法是使用.hxx文件.像这样:在你的头文件里面,Jh,放:

#ifndef _J_H__
#define _J_H__

template <class T> class J{  // member definitions };

#include "j.hxx"

#endif // _J_H__
Run Code Online (Sandbox Code Playgroud)

然后,在j.hxx中你将拥有

template <class T> J<T>::J() { // constructor implementation }

template <class T> J<T>::~J() { // destructor implementation }

template <class T> void J<T>::memberFunc() { // memberFunc implementation }

// etc.
Run Code Online (Sandbox Code Playgroud)

最后在你使用模板化类的.cpp文件中,让我们称它为K.cpp你将拥有:

#include "J.h" // note that this always automatically includes J.hxx    
void f(void)
{
     J<double> jinstance;  // now the compiler knows what the exact type is.
}
Run Code Online (Sandbox Code Playgroud)

  • 我不确定使用`.hpp`扩展名.按照惯例,在C++中,`.h`和`.hpp`几乎是可以互换的,所以你不能用`j.hpp`来填充`j.hpp`,它在功能上区别于`Jh`.[这里的惯例是`J.hxx`.](http://bytes.com/topic/c/answers/132004-inline-template-file-extensions) (2认同)