模板操作符重载函数上的未定义符号 [英] Undefined symbol on a template operator overloading function
问题描述
我有这个函数声明:
template< class T&
a :: A& a :: A :: operator<<(T out){
std :: cout<出口;
return(* this);
}
和此函数定义:
命名空间a {
...
A类{
...
模板< class T& A&运算符<<(T);
我称为:
a :: A b;
b<< 1;
这是Makefile:
app:main.o Ao
g ++ main.o Ao -o app
main.o:main.cpp
g ++ -c main .cpp
Ao:A.cpp
g ++ -c A.cpp
$ b b
它给了我:
未定义的符号:a :: A& a :: A :: operator<<
(int)
为什么?
在 T
(即 int
在你的case)实际上是已知的。然而,这不是在 main.cpp
被编译之前的情况。在编译 A.cpp
时,模板函数不会实例化为实际函数,因此生成的对象文件不包括函数的二进制版本。
有两种方法可以解决这个问题。
-
函数定义在头文件中。也就是说,make
template< class T>
a :: A& a :: A :: operator<<(T out){
std :: cout<出口;
return(* this);
}
头文件的一部分,并从
.cpp
文件。
这样做的效果是
包含此标题的.cpp
文件将能够使用模板的任何实例化,即任何值T
模板a :: A& a :: A :: operator<<(int out);
这将导致编译器实际实例化 A.cpp
,并将编译的函数包含在目标文件中。因此,链接器可以在链接 main.o
和 A.o
时找到它,一切正常。缺点是它只适用于为您提供了显式实例化的特定类型(在这种情况下,只有 int
)。
I have this function declaration:
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
and this function definition:
namespace a {
...
class A {
...
template<class T> A& operator<<(T);
And I call it as:
a::A b;
b << 1;
and this is the Makefile:
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
and it gives me:
Undefined symbols: a::A& a::A::operator<< <int>(int)
why is that?
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); }
a part of the header file, and remove the function definition from the
.cpp
file.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 ofT
.Alternatively, include an explicit template instantiation statement in
A.cpp
:template a::A& a::A::operator<<(int out);
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 linkingmain.o
andA.o
together, and all is fine. The disadvantage is that it will only work for the specific types (in this case, onlyint
) that you provided explicit instantiations for.
这篇关于模板操作符重载函数上的未定义符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!