带有模板的c ++类无法找到其构造函数

时间:2009-03-13 20:05:13

标签: c++ templates

我有一个问题,我真的不明白。我有一个Node节点。

template<class T>
class node {
protected:
    T _data;
public:
    node(T data);   
};

这是在“node.h”文件中。在“node.cpp”文件中,有这个构造函数:

#include "node.h"

template<class T>
node<T>::node (T data) {
    _data = data;
}

虽然编译器没有发现错误,但链接器(ld)告诉我:

  
    

/ usr / bin / ld:未定义的符号:

         

节点&lt; INT&GT; ::节点(int)的

  

奇怪的部分......如果我将构造函数从.cpp移动到.h文件,一切正常。问题在哪里?

7 个答案:

答案 0 :(得分:23)

问题是模板不是类 - 您通常不会将它们写在两个单独的文件中。模板类是编译器用于生成类的代码。因此,您的实现代码需要有效内联,即在您发现的标题中。

要更全面地解释为什么必须采用这种方式,请参阅C++ FAQ Lite

答案 1 :(得分:13)

作为一般规则,您必须将所有模板成员放在头文件中。模板是在使用的基础上编译的,因此整个定义需要在任何使用它们的地方都可用。将代码放在头文件中将解决该问题。

只有在CPP文件中使用模板时,才能将模板定义放在CPP文件中。原因是它符合整个定义可用于编译的标准。

将node.cpp的内容移动到node.h将解决问题。

奇怪的情景

然后,您还可以将所有内容放入CPP文件中并包含CPP文件。 C ++以这种方式很灵活。我只提到这个,因为我之前见过。当我的下颚撞到我的桌子顶部时,我的下巴确实受伤了。

答案 2 :(得分:1)

当您使用 node<int>时,您很可能不会包含node.cpp。因此,编译器无法实例化node<int>::node<int>构造函数。通常,您将所有模板代码(包括方法的所有实现)放在头文件中,或者包含在其中的内容。

答案 3 :(得分:1)

普遍接受的做法是将所有实现放在.h文件中,以便可以根据需要从模板生成类。

如果您提前知道您的模板将被实例化的类型,您可能会作弊。只需确保您的.cpp包含您需要的每种类型和方法的用例。用例在模板代码之后是很重要的。例如。对于“node.cpp”,请使用

#include "node.h"

template<class T>
node<T>::node (T data) {
    _data = data;
}

void dummy(void)
{
    node<int> intnode(0);
    node<double> doublenode(0.0);
}

答案 4 :(得分:1)

// You can put templates declaration in header and definition in source  
// node.h or wherever you include file gets included
extern template class node<int>;

// node.cpp or where ever source file you want to use it
// But use it only once for each type of generated class
template class node<int>;

答案 5 :(得分:0)

除非调用该函数,否则编译器不会输出任何代码,链接器也无法找到它。

您应该将该函数放在它所属的标题中。

答案 6 :(得分:0)

隐式实例化已关闭,您需要

template class node<int>;

代码中的某处(可能是node.cpp)

编辑:糟糕的答案,情况可能并非如此。