通过引用,源在操作过程中被修改

Pass by reference, source being modified mid-operation

本文关键字:操作过程 过程中 修改 操作 引用      更新时间:2023-10-16

我正在编写一个程序,通过高斯消去法求解矩阵形式的方程组。然而,我遇到了一个有趣的问题:如果我的算术运算符通过引用,那么行的规范化会给出不正确的结果。

在我的实现中,矩阵由多个矢量组成,所以行运算只是矢量运算。以下是相关功能:

矢量:

T& operator[] (const int i);
const T& operator[] (const int i) const;
Vector<T>& operator/=(const T& rhs);
template<class T>
Vector<T>& Vector<T>::operator/=(const T& rhs)
{
  if (rhs == 0)
  {
    throw DivideByZeroException();
  }
  for (int i = 0; i < _size; ++i)
  {
    _data[i] /= rhs;
  }
  return *this;
}

矩阵:

Vector<T>& operator[] (const int i);
const Vector<T>& operator[] (const int i) const;

(这样,单个[]用于访问一行,双[][]用于访问元素。(

下面是导致问题的原因:

mat[i] /= mat[i][i];

这里的问题是,此操作在某个点修改mat[i][i],然后使用修改后的值,因为operator/=使用传递引用。

问题:将运算符(和所有类似运算符(更改为按值传递更好,还是只更改导致问题的行更好?是否假设所有操作符都是参考的,从而使像上面这样的行总体上不好?

实际上,我想我会把我的评论作为一个完整的答案,问题不是来自于/=运算符的实现,而是很大程度上来自于调用行本身。正如我所说,这不应该给出一个可预测的(法律(结果。因为语言在标准中说得很清楚,并以i = i++ + ++i;为例说明了这一点。

所以我的建议是,不要试图把这件事作为你对客户的善意的一种特殊姿态,因为这样做的客户违反了比你的课程规范更重要的合同。