C++ 模板,未定义的引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/648900/
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++ templates, undefined reference
提问by Daniel Sloof
I have a function declared like so:
我有一个像这样声明的函数:
template <typename T>
T read();
and defined like so:
并定义如下:
template <typename T>
T packetreader::read() {
offset += sizeof(T);
return *(T*)(buf+offset-sizeof(T));
}
However, when I try to use it in my main() function:
但是,当我尝试在 main() 函数中使用它时:
packetreader reader;
reader.read<int>();
I get the following error from g++:
我从 g++ 收到以下错误:
g++ -o main main.o packet.o
main.o: In function `main':
main.cpp:(.text+0xcc): undefined reference to `int packetreader::read<int>()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
Can anyone point me into the right direction?
谁能指出我正确的方向?
采纳答案by strager
You need to use the export
keyword. However, I don't think G++ has proper support, so you need to include the template function's definition in the header so the translation unit can use it. This is because the <int>
'version' of the template hasn't been created, only the <typename T>
'version.'
您需要使用export
关键字。但是,我认为 G++ 没有适当的支持,因此您需要在标题中包含模板函数的定义,以便翻译单元可以使用它。这是因为<int>
尚未创建模板的“版本”,只有<typename T>
“版本”。
An easy way is to #include
the .cpp file. However, this can cause problems, e.g. when other functions are in the .cpp file. It will also likely increase the compile time.
一个简单的方法是#include
.cpp 文件。但是,这可能会导致问题,例如当其他函数位于 .cpp 文件中时。它也可能会增加编译时间。
A clean way is to move your template functions into its own .cpp file, and include that in the header oruse the export
keyword and compile it separately.
一种干净的方法是将您的模板函数移动到它自己的 .cpp 文件中,并将其包含在头文件中或使用export
关键字并单独编译它。
回答by jalf
The problem is that a function template is not a function. It's a template for creating functions as needed.
问题是函数模板不是函数。它是根据需要创建函数的模板。
So for a template to work, the compiler intuitively needs two pieces of information: The template itself, and the type that should be substituted into it.
This is unlike a function call, which the compiler can generate as soon as it knows that the function exists. It doesn't need to know what the function does, just that it looks like void Frobnicate(int, float)
, or whatever its signature is.
因此,要使模板工作,编译器直观地需要两条信息:模板本身,以及应替换到其中的类型。这与函数调用不同,编译器可以在知道函数存在后立即生成函数调用。它不需要知道函数做什么,只需要知道它的样子void Frobnicate(int, float)
,或者它的签名是什么。
When you declare the function template without defining it, you're only telling the compiler that such a template exists, but not what it looks like. That's not enough for the compiler to be able to instantiate it, it has to be able to see the full definition as well. The usual solution is to put the entire template in a header that can be included where needed.
当你声明函数模板而不定义它时,你只是告诉编译器这样的模板存在,而不是它的样子。这对于编译器能够实例化它是不够的,它还必须能够看到完整的定义。通常的解决方案是将整个模板放在一个标题中,可以在需要的地方包含它。
回答by vava
The best practice with template functions is to define them in header files. They are created at compile time so compiler has to have definition around to do so.
模板函数的最佳实践是在头文件中定义它们。它们是在编译时创建的,因此编译器必须有定义才能这样做。
When export
for templates would be more supported this wouldn't be the case though but right now it still hardly can be used.
当export
for 模板将得到更多支持时,情况并非如此,但现在它仍然几乎无法使用。
回答by Baiyan Huang
Is their any compiler support template separate compilation?
他们的任何编译器支持模板是否单独编译?
As I know the common practice is declare and implement template functions in the header file
据我所知,通常的做法是在头文件中声明和实现模板函数