C++ 模板运算符重载函数上的未定义符号
我有这个功能声明:C++ 模板运算符重载函数上的未定义符号,c++,templates,namespaces,operator-overloading,C++,Templates,Namespaces,Operator Overloading,我有这个功能声明: template<class T> a::A& a::A::operator<<(T out) { std::cout << out; return (*this); } 它给了我: 未定义的符号:a::a&a::a::operator一旦T表示的类型(即在您的例子中,int表示的类型)实际已知,函数模板将在编译时转换为实际函数。但是,在编译main.cpp之前,情况并非如此。编译A.cpp时,模板函数未实例化为实
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
它给了我:
未定义的符号:a::a&a::a::operator一旦
T
表示的类型(即在您的例子中,int
表示的类型)实际已知,函数模板将在编译时转换为实际函数。但是,在编译main.cpp
之前,情况并非如此。编译A.cpp
时,模板函数未实例化为实际函数,因此生成的目标文件不包括函数的二进制版本
有两种方法可以解决这个问题
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
这将导致编译器在编译A.cpp
时实际实例化模板,并将编译后的函数包含在目标文件中。因此,链接器可以在将main.o
和A.o
链接在一起时找到它,一切正常。缺点是它只适用于您为其提供显式实例化的特定类型(在本例中,仅适用于int
)尝试将定义更改为:
template<class T>
a::A& a::A::operator<< <T> (T out) {
std::cout << out;
return (*this);
}
模板
a::a&a::a::运算符是与函数定义在同一文件中的调用吗?或者它们是分开的,例如在.h和.cpp之间?@jogojapan,它们是分开的。每个代码的每个部分都在一个单独的文件中。第一个进入A.cpp
,第二个进入A.hpp
,第三个进入main.cpp
。这就是问题所在。您必须在.hpp文件中包含定义(顺便说一句,您在问题文本中混淆了声明和定义),或者在.cpp文件中为int
添加一个显式实例化。请参见此处:这是不正确的语法。主模板定义不允许像这样在尖括号中指定类型。(如果这是一个模板专门化,尖括号中的类型就不是模板参数。)@jogojapan好吧,好吧,我错了。我通常使用模板类,而不是函数或成员。对不起,这对我有用。。。声明和定义现在都在.hpp中,对吗?在.cpp文件中没有与此函数相关的内容,对吗?您是否删除了旧的.o文件并重新编译了所有内容?
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
template<class T>
a::A& a::A::operator<<(T out) {
std::cout << out;
return (*this);
}
template a::A& a::A::operator<<(int out);
template<class T>
a::A& a::A::operator<< <T> (T out) {
std::cout << out;
return (*this);
}