简体   繁体   English

C ++模板,未定义参考

[英]C++ templates, undefined reference

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? 谁能指出我正确的方向?

You need to use the export keyword. 您需要使用export关键字。 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. 但是,我认为G ++没有适当的支持,因此您需要在标头中包含模板函数的定义,以便翻译单元可以使用它。 This is because the <int> 'version' of the template hasn't been created, only the <typename T> 'version.' 这是因为尚未创建模板的<int> 'version',仅创建了<typename T> 'version'。

An easy way is to #include the .cpp file. 一种简单的方法是#include .cpp文件。 However, this can cause problems, eg when other functions are in the .cpp file. 但是,这可能会导致问题,例如,.cpp文件中有其他功能时。 It will also likely increase the compile time. 它还可能会增加编译时间。

A clean way is to move your template functions into its own .cpp file, and include that in the header or use the export keyword and compile it separately. 一种干净的方法是将模板函数移到其自己的.cpp文件中,并将其包含在标题中, 使用export关键字分别进行编译。

More information on why you should try and put template function definitions in its header file (and ignore export altogether). 有关为什么您应尝试将模板函数定义放入其头文件中的更多信息(而完全忽略export )。

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. 通常的解决方案是将整个模板放在可以在需要的地方包含的标头中。

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模板,虽然不是这种情况,但是现在仍然很难使用。

Is their any compiler support template separate compilation? 他们的任何编译器支持模板都是单独编译吗?

As I know the common practice is declare and implement template functions in the header file 据我所知,通常的做法是在头文件中声明并实现模板函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM