C ++模板,链接错误

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文件中隐藏了构造函数的定义。此定义适用于所有类型的T,包括T作为您使用的int类型,但实际上没有提供任何定义,因为它仍然只是一个声明。链接器找不到符号Array::Array()

现在,您可以添加这样的行:

1
Array<int> arr1;

到array.cpp文件的末尾,这使得编译器实例化链接器要查找的正确定义。然而,这只提供了一个定义,即Array的定义,而没有其他定义。

此解决方案将起作用,直到需要不同模板参数的Array,例如double,此时需要添加:

1
Array<double> arr2;

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

如果您需要C++来处理将来可能需要的任何类型,现在是将CTOR(以及可能所有其他成员函数)的定义移到头中的时间(并且删除.CPP文件,因为它没有任何剩余的内容)。


另一个答案是,只编译.cpp文件(不是主文件),检查对象文件的大小,然后创建一个空的.cpp文件,然后编译该空的.cpp。最后比较两个对象文件的大小。您将看到它们的大小相同,这意味着您的.cpp文件对编译器来说是零,因此链接器找不到任何内容。


如上所述,在C++中的模板中,编译器在编译时执行新方法的过程,问题是需要在那个时间知道THM的所有定义,所以所有类/函数声明必须是AR或HPP文件。