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

  • 11
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值