C++ 模板,链接错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1353973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ template, linking error
提问by Boris Raznikov
I have a problem in calling a template class I have. I declared a new type name Array, which is a template;
我在调用我拥有的模板类时遇到问题。我声明了一个新的类型名Array,它是一个模板;
In the .hpp file:
在 .hpp 文件中:
template <typename T>
class Array
{
public:
Array();
};
In the .cpp file:
在 .cpp 文件中:
template <typename T>
Array<T>::Array()
{
//Do something
}
In main:
在主要:
Array<int> arr;
I get Linkage error: unresolved external symbol to the ctor.
我收到 Linkage error: unresolved external symbol to thector。
Any Idea?
任何的想法?
回答by Tyler McHenry
Template functions, including member functions, must be written entirely in the header files. This means that if you have a template class, its implementation must be entirely in a header file. This is because the compiler needs to have access to the entire template definition (not just the signature) in order to generate code for each instantiation of the template.
模板函数,包括成员函数,必须完全写在头文件中。这意味着如果你有一个模板类,它的实现必须完全在一个头文件中。这是因为编译器需要访问整个模板定义(不仅仅是签名),以便为模板的每个实例化生成代码。
回答by Boris Raznikov
Put both the template declaration and the template function definitions in the header file. Most C++ compilers do not easily support the separate compilation model for templates,
将模板声明和模板函数定义都放在头文件中。大多数 C++ 编译器不容易支持模板的单独编译模型,
回答by moonshadow
If the definition of a templated function is not visible at the point where it is used (i.e. is not in the header or the same CPP file), you need to tell the compiler which instantiations to make.
如果模板化函数的定义在使用时不可见(即不在头文件或同一个 CPP 文件中),则需要告诉编译器要进行哪些实例化。
回答by quamrana
The problem you have here is that you have hidden the definition of the constructor in the .cpp file. This definition applies to alltypes T
, including T
as an int
that you use, but actually supplies no definitions whatsoever because its still only a declaration.
The linker cannot find the symbol Array<int>::Array()
.
您在这里遇到的问题是您在 .cpp 文件中隐藏了构造函数的定义。这个定义适用于所有类型T
,包括T
为int
你使用,但实际上没有提供任何的定义,因为它仍然只是一个声明。
链接器找不到符号Array<int>::Array()
。
Now, you can add a line like this:
现在,您可以添加如下一行:
Array<int> arr1;
to the end of your Array.cpp file and this makes the compiler instantiatethe correct definition that the linker is looking for. However, this only supplies onedefinition, that of Array<int>
and no other.
到 Array.cpp 文件的末尾,这使编译器实例化链接器正在寻找的正确定义。但是,这仅提供了一个定义,即 ofArray<int>
而没有其他定义。
This solution will work, until you need an Array
of a different template parameter, say, double
, at which point you would need to add:
此解决方案将起作用,直到您需要Array
一个不同的模板参数,例如,,double
此时您需要添加:
Array<double> arr2;
to the end of your Array.cpp file - now you can see how this is unsustainable!
到 Array.cpp 文件的末尾 - 现在您可以看到这是不可持续的!
If you need C++ to work with anytype that you might want in the future, now is the time to move the definition of the ctor (and presumably all the other member functions) up into the header (and delete the .cpp file as it won't have anything left in it).
如果您需要 C++ 来处理您将来可能想要的任何类型,现在是时候将 ctor(以及可能所有其他成员函数)的定义移到头文件中(并删除 .cpp 文件,因为它不会留下任何东西)。
回答by Boris Raznikov
As mentioned above, in templates in C++ the process of new methods is executing by the compiler at compile time, the problem is that it needs to know all definition of thm during that time, so all class/function declaration must be ar h or hpp files.
如上所述,在 C++ 中的模板中,新方法的过程是在编译时由编译器执行的,问题是它需要知道这段时间内 thm 的所有定义,因此所有类/函数声明必须是 ar h 或 hpp文件。
回答by mert inan
Another answer, compile just your .cpp file (not the main) and check the size of the object file then create an empty.cpp file then compile that empty.cpp. finally compare the size of the both object files. You will see that they have the same size which means your .cpp file is nothing to compiler, so linker can not find anything.
另一个答案,只编译您的 .cpp 文件(不是主文件)并检查目标文件的大小,然后创建一个 empty.cpp 文件,然后编译该 empty.cpp。最后比较两个目标文件的大小。您会看到它们具有相同的大小,这意味着您的 .cpp 文件对编译器来说没有任何意义,因此链接器找不到任何东西。