在练习模板类的重载输入输出运算符时,编译器提示“无法解析的外部符号”,代码如下:
template
class matrix
{
friend ostream& operator<<(ostream &out, const matrix &m);
friend istream& operator>>(sstream &in, matrix &m);
public:
......
private:
int theRows; //矩阵行数
theColumns; //矩阵列数
T *element; //矩阵元素用一维数组存储
};
......
template
ostream& operator<<(ostream &out, const matrix &m)
{
for (int i = 0; i < m.theRows; i++)
{
for (int j = 0; j < m.theColumns; ++j)
out << m.element[i * m.theColumns + j] << " ";
out << endl;
}
return out;
}
template
istream& operator>>(istream &in, matrix &m)
{
cout << "Enter " << m.theRows * m.theColumns << " element: ";
for (int i = 0; i < m.theRows * m.theColumns; i++)
in >> m.element[i];
if (!in)
throw illegalInputData("filed to input");
return in;
}
这是因为代码中用到模板类template
而在类内声明友元函数的时候也用到了
,所以此时友元函数是依赖于类的实现而实现的,编译器才会报错。
对此我们要两种解决方法。
1、依赖于两个成员函数output()和input(),而可以省去用友元声明,代码如下:
......
template
class matrix
{
public:
......
void output(ostream &out) const;
void input(istream &in);
......
private:
int theRows; //矩阵行数
theColumns; //矩阵列数
T *element; //矩阵元素用一维数组存储
};
......
template
void matrix::output(ostream &out)
{
for (int i = 0; i < theRows; i++)
{
for (int j = 0; j < theColumns; ++j)
out << element[i * theColumns + j] << " ";
out << endl;
}
}
template
ostream& operator<<(ostream &out, const matrix &m)
{
m.output(out);
return out;
}
template
void matrix::input(istream &in)
{
cout << "Enter " << theRows * theColumns << " element: ";
for (int i = 0; i < theRows * theColumns; i++)
in >> element[i];
if (!in)
throw illegalInputData("filed to input");
}
template
istream& operator>>(istream &in, matrix &m)
{
m.input(in);
return in;
}
2、改变友元与类模板的对应关系为多对多(即若T为int
,U为vector
依然为友元关系),代码如下:
template <typename T>
class matrix
{
template <typename U>
friend ostream& operator<<(ostream &out, const matrix &m);
template <typename U>
friend istream& operator>>(sstream &in, matrix &m);
public:
......
private:
......
};
......
template <typename U>
ostream& operator<<(ostream &out, const matrix &m)
{
......
}
template <typename U>
istream& operator>>(istream &in, matrix &m)
{
......
}
3、改变友元与类模板的对应关系为一对一(友好关系被限定在相同类型的实例化),代码如下:
//前置声明
template <typename T>
ostream& operator<<(ostream &out, const matrix &m);
template <typename T>
friend istream& operator>>(sstream &in, matrix &m);
template <typename T>
class matrix
{
friend ostream& operator<<(ostream &out, const matrix &m);
friend istream& operator>>(sstream &in, matrix &m);
public:
......
private:
......
};
......
template <typename T>
ostream& operator<<(ostream &out, const matrix &m)
{
......
}
template <typename T>
istream& operator>>(istream &in, matrix &m)
{
......
}
关于更具体的模板类中的友元声明,参见《C++ primer》第十六章:模板与泛型编程