首页 文章

C模板,未定义的引用

提问于
浏览
28

我有一个声明如下的函数:

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 回答

  • 24

    问题是函数模板不是函数 . 它是根据需要创建函数的模板 .

    因此,为了使模板起作用,编译器直观地需要两条信息:模板本身以及应该替换它的类型 . 这与函数调用不同,只要知道函数存在,编译器就可以生成函数调用 . 它不需要知道函数的作用,只是它看起来像 void Frobnicate(int, float) ,或者它的签名是什么 .

    当你声明函数模板而不定义它时,你只是告诉编译器这样的模板是存在的,而不是它的样子 . 这还不足以让编译器能够实例化它,它也必须能够看到完整的定义 . 通常的解决方案是将整个模板放在可以包含在需要的 Headers 中 .

  • 12

    模板函数的最佳实践是在头文件中定义它们 . 它们是在编译时创建的,因此编译器必须有定义才能这样做 .

    export for templates更受支持时,情况并非如此,但现在它仍然难以使用 .

  • 4

    您需要使用 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).

  • 0

    他们的任何编译器支持模板是否单独编译?

    据我所知,通常的做法是在头文件中声明并实现模板函数

相关问题