我有一个管理数据的课程。
我希望只返回其中的一部分数据,但由于这是一个多次完成的过程,我不希望只是将数据复制到容器中并返回容器。
如果我可以发送引用或类似的东西,那将是很好的。想到了迭代器。但是因为我使用 Eigen3 Matrix (它没有迭代器(无论如何都是2D矩阵))
我在考虑模拟(?)迭代器的行为, 类似的东西:
typedef unsigned int Index;
class MatrixIterator
{
public:
MatrixIterator(Eigen::MatrixXd *m, Index min, Index max):
_col(0), _index(0), _min(min), _max(max), _matrix(m)
{}
void operator++ ()
{
if (_index + _min + 1 != _max)
_index++;
}
void operator--()
{
if (_index != _min)
_index--;
}
double operator*()
{
return _matrix->operator() (_index + _min, _col);
}
void setCol(Index col) { _col = col; }
Index min() { return _min; }
Index max() { return _max; }
private:
// the matrix is 2D we can select
// on which column we want to iterate
Index _col;
// current position
Index _index;
// select the range on which the user can iterate
Index _max;
Index _min;
// the matrix on which we want to iterate over
Eigen::MatrixXd* _matrix;
}
MatrixIterator
继承我的std::iterator
,以便stl
能够将其理解为通常的迭代器吗?我读过:
编辑:我想迭代矩阵的一部分(这就是为什么我有_min和_max),我操作的数据是时间序列,所以数据已经被排序。 我认为我们可以将MatrixIterator视为对数据查询的响应。
答案 0 :(得分:2)
我之前从未真正使用过迭代器,它是否正确?
这是一个好的开始。这个想法是正确的,但你遗漏了一些东西。首先,您没有足够的运营商。确保检查reference并提供您可以合理提供的每个操作员(唯一可能有用或无用的是随机访问操作员,因为在这种情况下可能更难实施)。其次,您需要为迭代器类提供iterator traits。这通常是通过在迭代器类中创建必要的嵌套typedef来完成的(您也可以为您的类专门设置std::iterator_traits
模板,但我会说这只是在您真的无法添加嵌套的typedef时)。
我可以从
std::iterator
继承我的MatrixIterator,以便stl能够将其理解为通常的迭代器吗?
不,一般来说,你不应该继承std::iterator
类。 STL是模板库(通用编程(GP)),因此不使用OOP中的基类继承模型。 STL算法将迭代器作为模板参数,并且通常会根据算法的要求使用它们(或者尽可能地使用与迭代器类型相关联的iterator_category
特性)。这是generic programming,而不是面向对象的编程,它是苹果和橘子。
你知道更好的方法吗?
嗯,一种方便的方法是使用像boost::iterator_facade
这样的类模板(参见ref),它提供了一种自动“填空”机制来创建迭代器。它使用众所周知且非常有用的Curiously Recurring Template Pattern(或简称CRTP)。这很有用,因为实现迭代器所需的所有运算符可能非常冗长和重复,并且通常只依赖于几个核心操作(在使用像{{1这样的CRTP类时,您需要“填写”所有这些操作}})。