C ++在模板类中重载operator +

时间:2016-03-07 20:18:55

标签: c++ templates operator-overloading

operator+

我在使用非模板类之前没有问题地重载Matrix<U> Matrix<U>::operator+(const Matrix<U>&, const Matrix<U>&)。这里我使用的是模板类。

friend必须采用零或一个参数。

似乎编译器忽略了friend template<typename U> Matrix<U> operator+(const Matrix<U>& a, const Matrix<U>& b); 关键字。

我也试过

expected unqualified-id before 'template'

但是这给了我一个不同的编译器错误。

operator+

如何使用模板类重载{{1}}?

3 个答案:

答案 0 :(得分:2)

首先,我建议改为重载+=,然后用++=。其次,朋友通常不应该是模板。

template<typename T>
class Matrix
{
  friend Matrix operator+(Matrix a, const Matrix& b) {
    a += b;
    return std::move(a);
  }
  friend Matrix& operator+=(Matrix& a, const Matrix& b) {
    a.increase_by(b);
    return a;
  }
protected:
  void increase_by( const Matrix& other );

  size_t _m = 0
  size_t _n = 0;
  std::vector<T> _alloc;
};

template<class T>
void Matrix<T>::increase_by(const Matrix<T>& other) {
  if(this->_m == other._m && this->_n == other._n) {
    for (auto i = 0; i < _m*_n; ++i) {
      _alloc[i] += other._alloc[i];
    }
    // ...
  } else {
    throw "Matrix dimension mismatch error";
  }
}

请注意,通过高效移动,上面的内容将为您提供合理有效的a+b+c+d+e,因为lhs会被创建一次并重复移动。

答案 1 :(得分:2)

您可以使用成员函数或非成员函数重载+运算符。

当它是一个成员函数时,运算符的LHS是调用函数的对象,运算符的RHS是函数的参数。因此,成员函数的唯一参数是RHS。

当它是一个成员函数时,运算符的LHS是函数的第一个参数,运算符的RHS是函数的第二个参数。

会员功能

template<typename T>
class Matrix
{
  Matrix operator+(const Matrix& rhs) const {
    ...
  }
};

如果要在类定义之外实现它,可以使用:

template<typename T>
  Matrix<T> Matrix<T>::operator+(const Matrix& rhs) const {
    ...
  }

非会员功能

template<typename T>
class Matrix
{
  Matrix operator+(const Matrix& lhs, const Matrix& rhs) {
    ...
  }
};

如果要在类定义之外实现它,则需要添加一些前向声明代码:

// Forward declare the class template
template <typename T> class Matrix;

// Declare the function
template <typename T> Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs);

// Declare the friend in the class definition
template <typename T>
class Matrix
{
   friend Matrix operator+<T>(const Matrix& lhs, const Matrix& rhs);
   //                     ^^^^ 
   // This makes operator+<int> a friend of Matrix<int>, not a friend
   // of Matrix<double>
};

然后实现函数

template <typename T> Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs)
{
    ...
}

通过此设置,oprator+<int>仅是Matrix<int>的朋友,而不是friend的{​​{1}}。

如果您使用

Matrix<double>

然后,template <typename U> friend Matrix<U> operator+(const Matrix<U>& a, const Matrix<U>& b); 的所有实例化都是operator+所有实例化的朋友,您不需要。

<强>更新

示例工作代码:

Matrix

答案 2 :(得分:0)

解决方案:不显式声明模板,它们是自动生成的。也许有人可以更详细地解释原因?

friend
Matrix operator+(const Matrix& a, const Matrix& b)
{
    if(a._m == b._m && a._n == b._n)
    {
        Matrix ret(a._m, a._n);

        return ret;
    }
    else
    {
        throw "Matrix dimension mismatch error";
    }
}