C++模板,链接错误

Bor*_*kov 34 c++ linker templates

我在调用模板类时遇到问题.我声明了一个新的类型名称Array,它是一个模板;

在.hpp文件中:

template <typename T>
class Array
{
public:
   Array();
};
Run Code Online (Sandbox Code Playgroud)

在.cpp文件中:

template <typename T>
Array<T>::Array()
{
//Do something
}
Run Code Online (Sandbox Code Playgroud)

主要:

Array<int> arr;
Run Code Online (Sandbox Code Playgroud)

我得到了Linkage错误:未解析的外部符号到ctor.

任何的想法?

Tyl*_*nry 62

模板函数(包括成员函数)必须完全写在头文件中.这意味着如果您有模板类,则其实现必须完全在头文件中.这是因为编译器需要访问整个模板定义(而不仅仅是签名)才能为模板的每个实例化生成代码.

  • 从技术上讲,这不是一项要求.您可以在某些编译单元中显式实例化模板并在其他地方使用该模板,但这需要相当多的手动内务处理(为项目中使用的每个新类型添加显式实例化)甚至可能使其无法实现(如果必须使用未知类型工作). (7认同)

小智 9

将模板声明和模板函数定义放在头文件中.大多数C++编译器不容易支持模板的单独编译模型,


moo*_*dow 6

如果模板化函数的定义在使用它的位置不可见(即不在标题或相同的CPP文件中),则需要告诉编译器要进行哪些实例化.


qua*_*ana 5

这里的问题是您已在.cpp文件中隐藏了构造函数的定义。这个定义适用于所有类型T,包括Tint你使用,但实际上没有提供任何的定义,因为它仍然只是一个声明。
链接器找不到符号Array<int>::Array()

现在,您可以添加如下一行:

Array<int> arr1;
Run Code Online (Sandbox Code Playgroud)

到Array.cpp文件的末尾,这使编译器实例化链接程序正在寻找的正确定义。但是,这仅提供一个定义,Array<int>而没有其他定义。

该解决方案将一直有效,直到需要Array一个不同的模板参数(例如)为止double,此时您需要添加:

Array<double> arr2;
Run Code Online (Sandbox Code Playgroud)

到Array.cpp文件的末尾-现在您可以看到这是不可持续的!

如果您需要C ++处理将来可能需要的任何类型,现在是时候将ctor的定义(可能还有其他所有成员函数)移到头文件中(并删除.cpp文件)不会有任何剩余)。