C ++模板,链接错误

时间:2009-08-30 14:18:12

标签: c++ templates linker

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

在.hpp文件中:

template <typename T>
class Array
{
public:
   Array();
};

在.cpp文件中:

template <typename T>
Array<T>::Array()
{
//Do something
}

主要:

Array<int> arr;

我收到了Linkage错误:未解析的外部符号给ctor。

任何想法?

6 个答案:

答案 0 :(得分:59)

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

答案 1 :(得分:8)

同时放置模板声明和模板功能 头文件中的定义。大多数C ++编译器不容易支持模板的单独编译模型,

答案 2 :(得分:6)

如果模板化函数的定义在使用它的位置不可见(即不在标题或相同的CPP文件中),则需要tell the compiler which instantiations to make

答案 3 :(得分:4)

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

现在,您可以添加如下所示的行:

Array<int> arr1;

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

此解决方案可行,直到您需要Array其他模板参数,例如double,此时您需要添加:

Array<double> arr2;

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

如果您需要使用C ++来处理将来可能需要的任何类型,现在是时候将ctor的定义(可能是所有其他成员函数)移到标题(并删除.cpp文件,因为它不会留下任何内容)。

答案 4 :(得分:1)

如上所述,在C ++模板中,新方法的过程是由编译器在编译时执行的,问题是它需要在那段时间内知道thm的所有定义,因此所有类/函数声明必须是ar h或hpp文件。

答案 5 :(得分:1)

另一个答案,只编译.cpp文件(不是主文件)并检查目标文件的大小,然后创建一个empty.cpp文件,然后编译该empty.cpp。最后比较两个目标文件的大小。您将看到它们具有相同的大小,这意味着您的.cpp文件对编译器没有任何意义,因此链接器无法找到任何内容。

相关问题