我有一个声明如下的函数:
templateT read();
并定义如下:
templateT packetreader::read() { offset += sizeof(T); return *(T*)(buf+offset-sizeof(T)); }
但是,当我尝试在main()函数中使用它时:
packetreader reader; reader.read();
我从g ++得到以下错误:
g++ -o main main.o packet.o main.o: In function `main': main.cpp:(.text+0xcc): undefined reference to `int packetreader::read()' collect2: ld returned 1 exit status make: *** [main] Error 1
有人能指出我正确的方向吗?
您需要使用export
关键字.但是,我不认为G ++有适当的支持,因此您需要在标题中包含模板函数的定义,以便翻译单元可以使用它.这是因为
尚未创建模板的"版本",只有
"版本".
一个简单的方法是#include
.cpp文件.但是,这可能会导致问题,例如,当其他函数位于.cpp文件中时.它也可能会增加编译时间.
一种干净的方法是将模板函数移动到自己的.cpp文件中,并将其包含在标题中或使用export
关键字并单独编译.
有关为什么要尝试将模板函数定义放在其头文件中(并export
完全忽略)的更多信息.
问题是函数模板不是函数.它是根据需要创建函数的模板.
因此,为了使模板起作用,编译器直观地需要两条信息:模板本身以及应该替换它的类型.这与函数调用不同,只要知道函数存在,编译器就可以生成函数调用.它不需要知道函数的作用,只是它看起来像void Frobnicate(int, float)
,或者它的签名是什么.
当你声明函数模板而不定义它时,你只是告诉编译器这样的模板是存在的,而不是它的样子.这还不足以让编译器能够实例化它,它也必须能够看到完整的定义.通常的解决方案是将整个模板放在可以包含在需要的标题中.