用迭代器修改二维矢量
2d vector modify with iterator
我有一个使用vector
库的2d矩阵。我想更方便地迭代Matrix
,所以我创建了一个MatrixIterator
类。
矩阵.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*
返回,但也不起作用。我没有看到任何错误。出了什么问题,我该如何解决?
main.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 && main
编译
您需要在迭代器类中存储引用,而不是保存它的副本(迭代器只是数据的一个视图(。
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) {}
};
您还需要为矩阵设置非常量begin
和end
,可以使用非常量版本迭代器来更改底层值。函数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
,编译器会为您执行此操作。
int main() {
Matrix<int> m = Matrix<int>{3, 3};
for (auto& x : m) x = 10;
for (auto x : m) std::cout << x << " ";
return 0;
}
在线演示。
当试图更改矩阵值时,您正在迭代值,而不是引用。相反,尝试
for (auto& x : m.iterator())
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 我可以在没有堆栈的情况下在二叉搜索树中实现迭代器吗?
- 编译时二叉搜索树错误的反向迭代器表示"no matching function call for operator=()"
- 如何使用擦除和迭代器来删除二维向量中的项目
- 使用迭代器的二叉搜索
- 二维向量的迭代器
- boost::spirit:用于多维输入的迭代器和解析
- 二叉树编译错误的迭代器
- 使用迭代器位置的线性和二叉搜索
- C++:二叉搜索树 end() 迭代器
- 那么,是否可以像使用指针一样使用迭代器访问二维向量中的所有元素呢?
- 泛型c++多维迭代器
- 使用迭代器的二叉搜索,为什么我们使用"(end - begin)/2"?
- 如何访问(例如,cout)多维STL向量中的迭代器的当前值(c++)
- 创建多维迭代器