首页 > 解决方案 > 通过使用标量参数的运算符覆盖修改类成员

问题描述

我正在编写一个具有std::vectoras 成员的类,我希望能够通过使用默认运算符+/ +=*/*=等以标量作为参数来批量修改其数据,例如

MyClass<float> obj;
obj += 4.0;

我试图将运算符重载定义为:

template <class _type> 
matrix2D<_type>& matrix2D<_type>::operator=(matrix2D<_type> _mat){
    std::swap(_mat,*this);
    return *this;
};

template <class _type>
template <typename _input_type>
myClass<_type> myClass<_type>::operator*(_input_type _val) { 
    for (int i = 0; i < data.size(); ++i) data[i] *= _val; 
    return *this;
};

template <class _type>
template <typename _input_type>
myClass<_type> myClass<_type>::operator*=(_input_type _val) { 
    for (int i = 0; i < data.size(); ++i) data[i] *= _val; 
    return *this;
};

我没有收到编译或运行时错误,但值保持不变。我尝试了多种不同类型的返回值(MyClass&, void)并将myClass对象作为参数传递。我错过了什么?

标签: c++templatesoperator-overloading

解决方案


不要天真地写这个;y,否则它将是世界上最慢的实现。绝对不要使用std::val_array,因为它没有使用我知道的任何编译器进行优化。它的概念已经死在水中我的博士论文中有一个 Matrix 课程,如果你关心那里得到启发:https ://github.com/kvahed/codeare/blob/master/src/matrix/Matrix.hpp

根据经验,坚持std::vector并使用<algorithm>like std::accumulate, std::transform, ... 中的功能。并且始终实现运算符的赋值版本并在其他任何地方使用它。

因此,例如涵盖标量和矩阵元素乘法:

template <typename T>
class Matrix {
  public:
  ...
  Matrix<T>& operator*=(const T& t) {
    if (t != T(1)) {
      std::transform(
        v_.begin(), v_.end(), v_.begin(), std::bind2nd(std::multiplies<T>(), t));
    }
    return *this;
  }
  Matrix<T>& operator*=(const Matrix<T>& m) {
    std::transform(
      v_.begin(), v_.end(), m.begin(), v_.begin(), std::multiplies<T>()));
    return *this;
  }
  template<typename S>
  Matrix<T> operator* (const S& s) {
    return *this *= s;
  }
  ...
  private:
    std::vector<T> v_;
}

但这忽略了您的 CPU 能够执行的 SIMD 指令集: https ://github.com/kvahed/codeare/blob/master/src/matrix/SIMDTraits.hpp

但是有一些事情你应该记住,事实证明这些事情并不重要。特别是,当您的矩阵未在堆上分配时,内存可能是未对齐的。这将彻底杀死你。手动计算会更快。 https://github.com/kvahed/codeare/blob/master/src/matrix/Allocator.hpp

说真的,要正确构建您想要构建的东西需要大量的工作和测试代码。

TLDR:如果您正在寻找幼稚的实现,请<algorithm>远离val_array. 随意使用我的东西。如果您有任何问题,请随时。


推荐阅读