"undefined reference to `operator>>(std::istream&, Complex<int>&)" 模板复杂<T>
"undefined reference to `operator>>(std::istream&, Complex<int>&)" for template Complex<T>
我的代码:
#include <iostream>
using std::cin;
using std::cout;
using std::istream;
using std::ostream;
template<typename T>
class Complex
{
T real, img;
public:
Complex():real(0), img(0){}
friend istream& operator>>(istream& input, Complex& c1);
friend ostream& operator<<(ostream& output, Complex& c1);
Complex operator+(Complex& c1);
};
template<typename T>
istream& operator>>(istream& input, Complex<T>& c1)
{
cout<<"Real: ";
input>>c1.real;
cout<<"Imag: ";
input>>c1.img;
return input;
}
template<typename T>
ostream& operator<<(ostream& output, Complex<T>& c1)
{
output<<c1.real<<"+"<<c1.img<<"i";
return output;
}
template<typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c1)
{
Complex temp;
temp.real = this->real + c1.real;
temp.img = this->img + c1.img;
return temp;
}
int main()
{
Complex<int> cmp1;
cin>>cmp1;
return 0;
}
我得到的错误是 cin>>cmp1
,即 undefined reference to 'operator>>(std::istream&, Complex<int>&)'
。但是我在我的代码中找不到任何错误。
如果我将复杂的非模板 class 设为 double 并删除所有与模板相关的代码,则代码有效,因此 operator>>()
的定义基本上是正确的。
当我制作 Complex
模板时有什么变化?
友元函数不是成员,因此它们不是隐式模板。那里的声明表明实例化类型 Complex<int>
存在 non-template 运算符。
您可以使用
template<typename U>
friend istream& operator>>(istream& input, Complex<U>& c1);
template<typename U>
friend ostream& operator<<(ostream& output, Complex<U>& c1);
问题是目前重载的友元函数是普通函数。如果你想让它们成为函数模板,那么你需要将 class 中的 friend declarations 更改为如下所示。
更正式地说,在您的原始代码中,operator<<
和 operator>>
用于 class 模板 Complex<>
不是函数模板,而是“普通”函数 如果需要,使用 class 模板实例化 。也就是说,它们是模板化实体。
有 2 种方法可以解决这个问题,下面给出了两种方法。
解决方案 1
template<typename T>
class Complex
{
//other members as before
//friend declarations
template<typename U>
friend istream& operator>>(istream& input, Complex<U>& c1);
template<typename V>
friend ostream& operator<<(ostream& output, Complex<V>& c1);
//other members as before
};
解决方案 2
//forward declarations
template<typename T>
class Complex;
template<typename U>
istream& operator>>(istream& input, Complex<U>& c1);
template<typename V>
ostream& operator<<(ostream& output,const Complex<V>& c1);
template<typename T>
class Complex
{
T real, img;
public:
Complex():real(0), img(0){}
//friend declarations
friend istream& operator>> <T>(istream& input, Complex<T>& c1);
friend ostream& operator<< <T>(ostream& output,const Complex<T>& c1);
Complex operator+(Complex& c1);
};
我的代码:
#include <iostream>
using std::cin;
using std::cout;
using std::istream;
using std::ostream;
template<typename T>
class Complex
{
T real, img;
public:
Complex():real(0), img(0){}
friend istream& operator>>(istream& input, Complex& c1);
friend ostream& operator<<(ostream& output, Complex& c1);
Complex operator+(Complex& c1);
};
template<typename T>
istream& operator>>(istream& input, Complex<T>& c1)
{
cout<<"Real: ";
input>>c1.real;
cout<<"Imag: ";
input>>c1.img;
return input;
}
template<typename T>
ostream& operator<<(ostream& output, Complex<T>& c1)
{
output<<c1.real<<"+"<<c1.img<<"i";
return output;
}
template<typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c1)
{
Complex temp;
temp.real = this->real + c1.real;
temp.img = this->img + c1.img;
return temp;
}
int main()
{
Complex<int> cmp1;
cin>>cmp1;
return 0;
}
我得到的错误是 cin>>cmp1
,即 undefined reference to 'operator>>(std::istream&, Complex<int>&)'
。但是我在我的代码中找不到任何错误。
如果我将复杂的非模板 class 设为 double 并删除所有与模板相关的代码,则代码有效,因此 operator>>()
的定义基本上是正确的。
当我制作 Complex
模板时有什么变化?
友元函数不是成员,因此它们不是隐式模板。那里的声明表明实例化类型 Complex<int>
存在 non-template 运算符。
您可以使用
template<typename U>
friend istream& operator>>(istream& input, Complex<U>& c1);
template<typename U>
friend ostream& operator<<(ostream& output, Complex<U>& c1);
问题是目前重载的友元函数是普通函数。如果你想让它们成为函数模板,那么你需要将 class 中的 friend declarations 更改为如下所示。
更正式地说,在您的原始代码中,operator<<
和 operator>>
用于 class 模板 Complex<>
不是函数模板,而是“普通”函数 如果需要,使用 class 模板实例化 。也就是说,它们是模板化实体。
有 2 种方法可以解决这个问题,下面给出了两种方法。
解决方案 1
template<typename T>
class Complex
{
//other members as before
//friend declarations
template<typename U>
friend istream& operator>>(istream& input, Complex<U>& c1);
template<typename V>
friend ostream& operator<<(ostream& output, Complex<V>& c1);
//other members as before
};
解决方案 2
//forward declarations
template<typename T>
class Complex;
template<typename U>
istream& operator>>(istream& input, Complex<U>& c1);
template<typename V>
ostream& operator<<(ostream& output,const Complex<V>& c1);
template<typename T>
class Complex
{
T real, img;
public:
Complex():real(0), img(0){}
//friend declarations
friend istream& operator>> <T>(istream& input, Complex<T>& c1);
friend ostream& operator<< <T>(ostream& output,const Complex<T>& c1);
Complex operator+(Complex& c1);
};