【问题标题】:Const Double Indexing with [][] in Matrix Class矩阵类中使用 [][] 的常量双索引
【发布时间】:2018-04-13 18:06:52
【问题描述】:

以下代码包含一个简单的 Matrix 类示例,使用“代理”Row 类启用双索引 [][]。

#include <valarray>
#include <iostream>

template <typename T>
class Matrix {

private:

  // Data members
  int nRows_;
  int nColumns_;
  std::valarray<T> data_;

public:

  // Constructor
  Matrix(const int nRows,
         const int nColumns)
    : nRows_{nRows},
      nColumns_{nColumns},
      data_{std::valarray<T>(nRows*nColumns)} {}

  // Row friend class to enable double indexing
  class Row {   
    friend class Matrix;

  private:

    // Constructor
    Row(Matrix& parent,
        int row)
      : parent_{parent},
        row_{row} {}

    // Data members
    Matrix& parent_;
    int row_;

  public:

    // Index columns
    T& operator[](int column) {
      int nColumns{parent_.nColumns_};
      int element{row_*nColumns + column};
      return parent_.data_[element];
    }
  };

  // Index rows
  Row operator[](int row) {
    return Row(*this, row);
  }
};

但是,这不允许 const 矩阵的双重索引。例如,下面的代码在包含最后一行时编译失败。

int main() {

  Matrix<int> a{3,3};
  const Matrix<int> b{3,3};
  std::cout << a[1][2];
  std::cout << b[1][2];
}

所以问题是,如何修改我的 Matrix 类以允许对 const Matrix 对象进行双重索引?

【问题讨论】:

    标签: c++ c++11 matrix operator-overloading


    【解决方案1】:

    由于bconst 矩阵,您需要添加索引运算符的const 版本。

    Row operator[](int row) const { ... }
    

    这将需要对Row 类(或第二个代理类)进行额外更改,以处理operator[]const Matrix &amp;const 重载。

    【讨论】:

    • 所以我尝试对Row operator[](int row) const { ... }const T&amp; operator[](int column) const { ... } 进行更改,但它仍然无法编译。我真的不明白为什么这不起作用,因此我认为我对为什么事情需要/不需要是 const 缺乏逻辑理解......
    • 还有const Matrix&amp; parent_;。所以总共有四个额外的常量。我现在也忽略了非常量版本。
    • @Watw 你真的不需要非常量版本,除非你的操作是为了改变你的类的字段
    【解决方案2】:

    我认为我对为什么事情需要/不需要是 const 缺乏逻辑理解

    这取决于您是否可以修改参数。一般来说operator[] 不应该改变对象(除非它改变了,但是……呃),它应该返回对对象资源的引用。多田!您的实现不允许这样做,因为 valarrayconst 然后。您不能将 const 矩阵引用分配给

     Matrix& parent_;
    

    结果

     Row(const Matrix& parent, int row)  
    

    为什么要存储 Matrix 本身...我已经存储了 valarray 的引用。

    实际上我会放弃容器并在堆中创建自己的透明数组。这样,Row 将引用数组的一部分和行的长度,开销几乎为零。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 2011-08-19
      • 2020-04-28
      • 2022-11-02
      • 1970-01-01
      相关资源
      最近更新 更多