在練習模板類的重載輸入輸出運算符時,編譯器提示“無法解析的外部符號”,代碼如下:
template <typename T>
class matrix
{
friend ostream& operator<<(ostream &out, const matrix<T> &m);
friend istream& operator>>(sstream &in, matrix<T> &m);
public:
......
private:
int theRows; //矩陣行數
theColumns; //矩陣列數
T *element; //矩陣元素用一維數組存儲
};
......
template <typename T>
ostream& operator<<(ostream &out, const matrix<T> &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 <typename T>
istream& operator>>(istream &in, matrix<T> &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 <typename T>
而在類內聲明友元函數的時候也用到了<T>
,所以此時友元函數是依賴於類的實現而實現的,編譯器纔會報錯。
對此我們要兩種解決方法。
1、依賴於兩個成員函數output()和input(),而可以省去用友元聲明,代碼如下:
......
template <typename T>
class matrix
{
public:
......
void output(ostream &out) const;
void input(istream &in);
......
private:
int theRows; //矩陣行數
theColumns; //矩陣列數
T *element; //矩陣元素用一維數組存儲
};
......
template <typename T>
void matrix<T>::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 <typename T>
ostream& operator<<(ostream &out, const matrix<T> &m)
{
m.output(out);
return out;
}
template <typename T>
void matrix<T>::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 <typename T>
istream& operator>>(istream &in, matrix<T> &m)
{
m.input(in);
return in;
}
2、改變友元與類模板的對應關係爲多對多(即若T爲int
,U爲vector<int>
依然爲友元關係),代碼如下:
template <typename T>
class matrix
{
template <typename U>
friend ostream& operator<<(ostream &out, const matrix<U> &m);
template <typename U>
friend istream& operator>>(sstream &in, matrix<U> &m);
public:
......
private:
......
};
......
template <typename U>
ostream& operator<<(ostream &out, const matrix<U> &m)
{
......
}
template <typename U>
istream& operator>>(istream &in, matrix<U> &m)
{
......
}
3、改變友元與類模板的對應關係爲一對一(友好關係被限定在相同類型的實例化),代碼如下:
//前置聲明
template <typename T>
ostream& operator<<(ostream &out, const matrix<T> &m);
template <typename T>
friend istream& operator>>(sstream &in, matrix<T> &m);
template <typename T>
class matrix
{
friend ostream& operator<<<T>(ostream &out, const matrix<T> &m);
friend istream& operator>><T>(sstream &in, matrix<T> &m);
public:
......
private:
......
};
......
template <typename T>
ostream& operator<<(ostream &out, const matrix<T> &m)
{
......
}
template <typename T>
istream& operator>>(istream &in, matrix<T> &m)
{
......
}
關於更具體的模板類中的友元聲明,參見《C++ primer》第十六章:模板與泛型編程