C++模板類中聲明友元函數重載輸入和輸出運算符時,提示無法解析的外部符號解決方案

在練習模板類的重載輸入輸出運算符時,編譯器提示“無法解析的外部符號”,代碼如下:

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》第十六章:模板與泛型編程

發佈了30 篇原創文章 · 獲贊 22 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章