【问题标题】:2d vector modify with iterator使用迭代器修改二维向量
【发布时间】:2021-05-16 07:00:56
【问题描述】:

我有一个使用vector 库的二维矩阵。而且我想更方便地迭代Matrix,所以我创建了一个MatrixIterator 类。

Matrix.cpp

#include <vector>

template <class T>
class MatrixIterator;

template <class T>
class Matrix
{
    friend class MatrixIterator<T>;

private:
public:
    std::vector<std::vector<T>> m;
    unsigned rows_;
    unsigned cols_;

    Matrix<T>(unsigned rows, unsigned cols);

    MatrixIterator<T> iterator() const
    {
        return {*this};
    }

    MatrixIterator<T> begin() const
    {
        return {*this};
    }

    MatrixIterator<T> end() const
    {
        return {*this, rows_, 0};
    }
}


template <class T>
class MatrixIterator
{
private:
    Matrix<T> matrix_;
    unsigned row_;
    unsigned col_;

public:
    MatrixIterator<T>(Matrix<T> m) : matrix_(m), row_(0), col_(0) {};
    MatrixIterator<T>(Matrix<T> m, unsigned row, unsigned col) : matrix_(m), row_(row), col_(col) {};

    MatrixIterator<T> begin() const
    {
        return {matrix_};
    }

    MatrixIterator<T> end() const
    {
        return {matrix_, matrix_.rows_, 0};
    }

    void inc()
    {
        if(++col_ >= matrix_.cols_)
        {
            row_++;
            col_ = 0;
        }
    }

    MatrixIterator<T>& operator++()
    {
        inc();
        return *this;
    }

    MatrixIterator<T> operator++(int)
    {
        inc();
        return *this;
    }

    bool operator!=(const MatrixIterator<T> &rhs) const
    {
        return (row_ != rhs.row_) || (col_ != rhs.col_);
    }

    T& operator*()
    {
        return matrix_.m[row_][col_];
    }
};


template <class T>
Matrix<T>::Matrix(unsigned rows, unsigned cols)
    : rows_(rows), cols_(cols)
{

    m.resize(cols);
    for (unsigned i = 0; i < cols; i++)
    {
        m[i].resize(rows);
        fill(m[i].begin(), m[i].end(), T());
    }
}

在下面的代码中,当我尝试使用迭代器操作值时,它不会改变值。 我尝试将值作为来自operator* 的指针返回,但它也不起作用。我没有看到任何错误。出了什么问题,我该如何解决?

ma​​in.cpp

#include "Matrix.cpp"
#include<iostream>
int main()
{
    Matrix<int> m = Matrix<int>{3,3};
    for(auto x: m.iterator())
        x = 10;
    for(auto x: m.iterator())
        std::cout << x << " ";
    // outputs 0 0 0 ~
}

g++ main.cpp -std=c++20 -g -o main &amp;&amp; main编译

【问题讨论】:

    标签: c++ multidimensional-array c++20


    【解决方案1】:

    您需要在迭代器类中存储一个引用,而不是保存它的副本(迭代器只是数据的视图)。

    template <class T>
    class MatrixIterator {
     private:
      Matrix<T>& matrix_;
      unsigned row_;
      unsigned col_;
    
     public:
      MatrixIterator<T>(Matrix<T>& m) : MatrixIterator<T>(m, 0, 0) {}
      MatrixIterator<T>(Matrix<T>& m, unsigned row, unsigned col)
          : matrix_(m), row_(row), col_(col) {}
    };
    

    而且您还需要非 const beginend 为您的矩阵,非常量版本迭代器可用于更改基础值。函数iterator() 可以在此处删除,因为在 c++ 代码中并不常见。

      MatrixIterator<T> begin() const { return {*this}; }
      MatrixIterator<T> begin() { return {*this}; }
    
      MatrixIterator<T> end() const { return {*this, rows_, 0}; }
      MatrixIterator<T> end() { return {*this, rows_, 0}; }
    

    要使用迭代器更改值,除了在主函数中更改复制的值之外,您还需要一个引用。这里不需要显式调用iterator,编译器会do it for you

    int main() {
      Matrix<int> m = Matrix<int>{3, 3};
      for (auto& x : m) x = 10;
      for (auto x : m) std::cout << x << " ";
      return 0;
    }
    

    Online demo.

    【讨论】:

      【解决方案2】:

      在尝试更改矩阵值时,您正在迭代 ,而不是引用。相反,尝试

      for (auto& x : m.iterator())
      

      【讨论】:

        猜你喜欢
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-16
        • 2020-11-27
        • 1970-01-01
        相关资源
        最近更新 更多