为非 stl 容器创建我自己的迭代器

Creating my own Iterators for non stl container

本文关键字:我自己 自己的 迭代器 创建 stl 为非      更新时间:2023-10-16

我有一个管理数据的类。

我只想返回其中的一部分数据,但由于这是一个将多次完成的过程,我不希望只复制容器内的数据并返回容器。

如果我能发送参考或类似的东西,那就太好了。迭代器浮现在脑海中。但是因为我使用 Eigen3 矩阵(它没有迭代器(无论如何是 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;
}
  • 我以前从未真正使用过迭代器,正确吗?
  • 我可以从std::iterator继承我的MatrixIterator,以便stl能够像通常的迭代器一样理解它吗?
  • 你知道做类似事情的更好方法吗?

我读过:

  • 创建我自己的迭代器 - 这并没有真正说实现迭代器,因为它们使用矢量迭代器
  • http://www.cplusplus.com/reference/iterator/
  • 如何使用迭代器迭代二维向量?

编辑:我只想迭代矩阵的一部分(这就是为什么我有_min和_max),我正在操作的数据是时间序列,因此数据已经排序。我认为我们可以将MatrixIterator视为对数据查询的响应。

我以前从未真正使用过迭代器,正确吗?

这是一个良好的开端。这个想法是正确的,但你错过了一些东西。首先,您没有足够的运算符。确保检查引用并提供可以合理提供的每个运算符(唯一可能有用也可能没有用的运算符是随机访问运算符,因为在这种情况下可能更难实现)。其次,您需要为迭代器类提供迭代器特征。这通常是通过在迭代器类中创建必要的嵌套 typedef 来完成的(您也可以为您的类专门化std::iterator_traits模板,但我想说这只是当你真的无法添加嵌套 typedefs 时)。

我可以从std::iterator继承我的矩阵迭代器,以便 stl 能够将其理解为通常的迭代器吗?

不,通常不应从 std::iterator 类继承。STL 是一个模板库(泛型编程 (GP)),因此不像 OOP 中那样使用基类继承模型。STL 算法将迭代器作为模板参数,并且通常会根据算法的要求(或与迭代器类型关联的iterator_category特征)使用它们。这是泛型编程,不是面向对象编程,它是苹果和橙子。

你知道做类似事情的更好方法吗?

好吧,一种方便的方法是使用像boost::iterator_facade这样的类模板(参见 ref),它提供了一种创建迭代器的自动"填空"机制。它使用众所周知且非常有用的奇怪重复模板模式(或简称 CRTP)。这很有用,因为实现迭代器所需的所有运算符可能非常冗长和重复,并且通常只依赖于几个核心操作(这是您在使用 CRTP 类时需要"填充"的全部boost::iterator_facade)。