[英]C++ templates, undefined reference
我有一个这样声明的函数:
template <typename T>
T read();
并定义如下:
template <typename T>
T packetreader::read() {
offset += sizeof(T);
return *(T*)(buf+offset-sizeof(T));
}
但是,当我尝试在main()函数中使用它时:
packetreader reader;
reader.read<int>();
我从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
谁能指出我正确的方向?
您需要使用export
关键字。 但是,我认为G ++没有适当的支持,因此您需要在标头中包含模板函数的定义,以便翻译单元可以使用它。 这是因为尚未创建模板的<int>
'version',仅创建了<typename T>
'version'。
一种简单的方法是#include
.cpp文件。 但是,这可能会导致问题,例如,.cpp文件中有其他功能时。 它还可能会增加编译时间。
一种干净的方法是将模板函数移到其自己的.cpp文件中,并将其包含在标题中, 或使用export
关键字分别进行编译。
问题在于功能模板不是功能。 它是用于根据需要创建函数的模板。
因此,要使模板正常工作,编译器会直观地需要两方面的信息:模板本身以及应替换为模板的类型。 这与函数调用不同,函数调用在知道该函数存在后就可以立即生成。 它不需要知道函数的作用,只要知道它看起来像void Frobnicate(int, float)
或它的签名是什么。
当您声明函数模板而不定义它时,您只是在告诉编译器这样的模板存在,而不是它的外观。 对于编译器来说,实例化还不够,它还必须能够看到完整的定义。 通常的解决方案是将整个模板放在可以在需要的地方包含的标头中。
模板功能的最佳实践是在头文件中定义它们。 它们是在编译时创建的,因此编译器必须对此进行定义。
如果不支持export
模板,虽然不是这种情况,但是现在仍然很难使用。
他们的任何编译器支持模板都是单独编译吗?
据我所知,通常的做法是在头文件中声明并实现模板函数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.