C++ template, linking error
调用模板类时出现问题。我声明了一个新的类型名数组,它是一个模板;
在.hpp文件中:
1 2 3 4 5 6 | template <typename T> class Array { public: Array(); }; |
在.cpp文件中:
1 2 3 4 5 | template <typename T> Array<T>::Array() { //Do something } |
在主要方面:
1 | Array<int> arr; |
我得到链接错误:未解析的外部符号到ctor。
有什么想法吗?
模板函数(包括成员函数)必须完全写入头文件中。这意味着如果您有一个模板类,它的实现必须完全在一个头文件中。这是因为编译器需要访问整个模板定义(不仅仅是签名),以便为模板的每个实例化生成代码。
同时放置模板声明和模板函数头文件中的定义。大多数C++编译器不容易支持模板的单独编译模型,
如果模板化函数的定义在使用时不可见(即不在头文件或同一个cpp文件中),则需要告诉编译器要进行哪种实例化。
这里的问题是您已经在.cpp文件中隐藏了构造函数的定义。此定义适用于所有类型的
现在,您可以添加这样的行:
1 | Array<int> arr1; |
到array.cpp文件的末尾,这使得编译器实例化链接器要查找的正确定义。然而,这只提供了一个定义,即
此解决方案将起作用,直到需要不同模板参数的
1 | Array<double> arr2; |
到array.cpp文件的末尾-现在您可以看到这是如何不可持续的!
如果您需要C++来处理将来可能需要的任何类型,现在是将CTOR(以及可能所有其他成员函数)的定义移到头中的时间(并且删除.CPP文件,因为它没有任何剩余的内容)。
另一个答案是,只编译.cpp文件(不是主文件),检查对象文件的大小,然后创建一个空的.cpp文件,然后编译该空的.cpp。最后比较两个对象文件的大小。您将看到它们的大小相同,这意味着您的.cpp文件对编译器来说是零,因此链接器找不到任何内容。
如上所述,在C++中的模板中,编译器在编译时执行新方法的过程,问题是需要在那个时间知道THM的所有定义,所以所有类/函数声明必须是AR或HPP文件。