问题描述
我有一个使用 selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,initialDate: selectedDate,initialDatePickerMode: DatePickerMode.day,firstDate: DateTime(1952),lastDate: DateTime(2003));
if (picked != null)
setState(() {
selectedDate = picked;
_dateController.text = DateFormat.yMd().format(selectedDate);
});
}
库的二维矩阵。我想更方便地迭代 vector
,所以我创建了一个 Matrix
类。
Matrix.cpp
MatrixIterator
在下面的代码中,当我尝试使用迭代器操作值时,它不会更改值。
我尝试将值作为来自 #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());
}
}
的指针返回,但它也不起作用。我没有看到错误。出了什么问题,我该如何解决?
main.cpp
operator*
使用 #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 ~
}
编译
解决方法
在尝试更改矩阵值时,您正在迭代 值,而不是引用。相反,尝试
for (auto& x : m.iterator())
,
您需要在迭代器类中存储一个引用,而不是保存它的副本(迭代器只是数据的视图)。
template <class T>
class MatrixIterator {
private:
Matrix<T>& matrix_;
unsigned row_;
unsigned col_;
public:
MatrixIterator<T>(Matrix<T>& m) : MatrixIterator<T>(m,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,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;
}