问题描述
我有这个函数声明:
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
和这个函数定义:
namespace a {
...
class A {
...
template<class T> A& operator<<(T);
我称之为:
a::A b;
b << 1;
这是生成文件:
app: main.o A.o
g++ main.o A.o -o app
main.o: main.cpp
g++ -c main.cpp
A.o: A.cpp
g++ -c A.cpp
它给了我:
未定义符号:a::A&a::A::operator<<
Undefined symbols: a::A& a::A::operator<< <int>(int)
这是为什么?
推荐答案
函数模板会在编译时变成一个实际的函数,一旦T
所代表的类型(即int
在你的情况下)实际上是已知的.但是,在编译 main.cpp
之前,情况并非如此.编译A.cpp
时,模板函数并未实例化为实际函数,因此生成的目标文件不包含该函数的二进制版本.
The function template will be turned into an actual function at compile time, once the type represented by T
(that is, int
in your case) is actually known. However, this is not the case before main.cpp
is compiled. At the time when A.cpp
is compiled, the template function is not instantiated into an actual function, therefore the object file generated doesn't include the binary version of the function.
有两种方法可以解决这个问题.
There are two ways to solve this.
在头文件中包含函数定义.也就是说,使
Include the function definition in your header file. That is, make
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
头文件的一部分,并从.cpp
文件中删除函数定义.
a part of the header file, and remove the function definition from the .cpp
file.
这样做的效果是任何 .cpp
文件包含这个头文件将能够使用模板的任何 实例化,即对于 T
的任何值.
The effect of this is that any .cpp
file that includes this header will be able to use any instantiation of the template, i.e. for any value of T
.
或者,在 A.cpp
中包含显式模板实例化语句:
Alternatively, include an explicit template instantiation statement in A.cpp
:
template a::A& a::A::operator<<(int out);
这将导致编译器在编译 A.cpp
时实际实例化模板,并将编译后的函数包含在目标文件中.因此链接器可以在将 main.o
和 A.o
链接在一起时找到它,一切都很好.缺点是它仅适用于您为其提供显式实例化的特定类型(在本例中,只有 int
).
This will cause the compiler to actually instantiate the template when A.cpp
is compiled, and to include the compiled function in the object file. Hence the linker can find it when linking main.o
and A.o
together, and all is fine. The disadvantage is that it will only work for the specific types (in this case, only int
) that you provided explicit instantiations for.
这篇关于模板运算符重载函数上的未定义符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!