我有一个声明如下的函数:
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
有人能指出我正确的方向吗?
4 回答
问题是函数模板不是函数 . 它是根据需要创建函数的模板 .
因此,为了使模板起作用,编译器直观地需要两条信息:模板本身以及应该替换它的类型 . 这与函数调用不同,只要知道函数存在,编译器就可以生成函数调用 . 它不需要知道函数的作用,只是它看起来像
void Frobnicate(int, float)
,或者它的签名是什么 .当你声明函数模板而不定义它时,你只是告诉编译器这样的模板是存在的,而不是它的样子 . 这还不足以让编译器能够实例化它,它也必须能够看到完整的定义 . 通常的解决方案是将整个模板放在可以包含在需要的 Headers 中 .
模板函数的最佳实践是在头文件中定义它们 . 它们是在编译时创建的,因此编译器必须有定义才能这样做 .
当
export
for templates更受支持时,情况并非如此,但现在它仍然难以使用 .您需要使用
export
关键字 . 但是,我在 Headers 中没有't think G++ has proper support, so you need to include the template function'的定义,因此翻译单位可以使用它 . 这是因为尚未创建模板的<int>
'version',只有<typename T>
'version.'一个简单的方法是
#include
.cpp文件 . 然而,这可能导致问题,例如,当其他函数在.cpp文件中时 . 它也可能会增加编译时间 .一种干净的方法是将模板函数移动到其自己的.cpp文件中,并将其包含在 Headers 中或使用
export
关键字并单独编译 .More information on why you should try and put template function definitions in its header file (and ignore export altogether).
他们的任何编译器支持模板是否单独编译?
据我所知,通常的做法是在头文件中声明并实现模板函数