在C ++中,使用自定义行迭代行为设计抽象数据集类的最佳方法是什么?

时间:2015-06-16 07:51:40

标签: c++ iterator const

我想设计一个抽象的Dataset类。派生类在存储数据和迭代方面有所不同。以下是一些派生类示例:

  • InMemoryDataset:将所有数据存储在内存中vector<Row>
  • StreamingTextDataset:不会将数据存储在内存中,也可以从文本文件中传输行。
  • StreamingBinaryDataset:也不会将数据存储在内存中,而是从二进制文件中流式传输行(如果需要,可以按随机顺序提供示例)。

这是我目前的设计,但我觉得它很尴尬,因为它不是严格抽象的(即它没有任何虚函数)。派生类通过派生Dataset类并使用正确的State对象初始化state_变量来扩展此State

是否有比这更简洁/更简单的设计?

class Dataset {
protected:
    class State {
    public:
        virtual ~State() {}
        virtual void Reset() = 0;
        virtual bool MoveNext() = 0;
        virtual const Row* Current() const = 0;
    };

    std::unique_ptr<State> state_;

public:
    struct Iterator {
        Iterator(State *state);
        const Row& operator*() const;
        const Row* operator->() const;
        Iterator operator++();
        bool operator!=(const Iterator & other);
    private:
        State *state_;
    };

    Iterator begin() const;
    Iterator end() const;
};

1 个答案:

答案 0 :(得分:0)

从你到现在为止,它似乎只是Range concept的封装。

  • 您希望能够遍历行

  • 有不同类型的范围

  • 迭代可能是有状态的

我不确定你需要自己的类层次结构而不是迭代器本身的内部多态性。问题是如何做到这一点。

如果您可以使用编译时多态性,可以使用boost::iterator_range

执行类似的操作
template<typename Iterator>
class Dataset : 
     public boost::iterator_range<Iterator>
...

并使用各种迭代器(可能使用std::istream_iterator,使用说boost::iterator_facade或任意组合的自定义迭代器)实例化它。

如果你必须具有运行时多态性,那么你只需要type erasure。我只想使用boost::iterator_facadeboost::any构建自定义迭代器。