C++ 模板,未定义的参考
我有一个函数声明如下:
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
任何人都可以指出我正确的方向吗?
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:
packetreader reader;
reader.read<int>();
I get the following error from 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要使用
export
关键字。 但是,我认为 G++ 没有适当的支持,因此您需要在标头中包含模板函数的定义,以便翻译单元可以使用它。 这是因为模板的
“version”尚未创建,仅创建了
“version”。一个简单的方法是
#include
.cpp 文件。 但是,这可能会导致问题,例如,当 .cpp 文件中有其他函数时。 它还可能会增加编译时间。一种简洁的方法是将模板函数移至其自己的 .cpp 文件中,并将其包含在标头中或使用
export
关键字并单独编译它。有关为什么应该尝试放置模板函数的更多信息其头文件中的定义(并完全忽略
导出
)。You need to use the
export
keyword. 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. This is because the<int>
'version' of the template hasn't been created, only the<typename T>
'version.'An easy way is to
#include
the .cpp file. However, this can cause problems, e.g. when other functions are in the .cpp file. 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.More information on why you should try and put template function definitions in its header file (and ignore
export
altogether).问题在于函数模板不是函数。 它是根据需要创建函数的模板。
因此,要使模板正常工作,编译器直观地需要两条信息:模板本身以及应替换为模板的类型。
这与函数调用不同,编译器一旦知道函数存在就可以生成函数调用。 它不需要知道该函数的作用,只需知道它看起来像
void Frobnicate(int, float)
或其签名是什么即可。当您声明函数模板而不定义它时,您只是告诉编译器这样的模板存在,而不是它的样子。 这对于编译器能够实例化它来说还不够,它还必须能够看到完整的定义。 通常的解决方案是将整个模板放在可在需要时包含的标头中。
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.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.他们的编译器是否支持模板单独编译?
据我所知,常见的做法是在头文件中声明并实现模板函数
Is their any compiler support template separate compilation?
As I know the common practice is declare and implement template functions in the header file