c – 使用迭代器实现状态机(ala生成器)
最近我需要实现生成一堆数字的小类.如果C有像
python这样的生成器会很方便,但遗憾的是并非如此.
所以我一直在考虑如何最好地实现这些类型的对象,以便于迭代和组合.当我们考虑容器上的迭代器时,它们基本上只将索引保存到元素中,而大部分信息都在容器本身中.这允许多个迭代器同时引用集合中的不同元素. 当它来到状态机时,很明显迭代器必须保持整个状态,因为几个迭代器需要能够独立.从这个意义上讲,状态机类更像是这些迭代器的“构建器”,它们是实际的状态机. 作为玩具示例,我已经实现了范围生成器(python中的ala xrange),可以在循环中使用: // using range-for from c++11 for (auto i : range<int>(1,30)) { cout << i << endl; } 代码可以在my bitbucket找到. 也就是说,将整个状态存储在迭代器中是很尴尬的,因为创建end()迭代器只是为了比较结束状态,如果状态是大量成员集合则会浪费空间. 有没有用简单的线性状态机完成任务,并用迭代器循环它们? 解决方法
如果仅支持前向迭代,则可以使用end()的不同类型然后使用begin().这是基本的想法
class iterator; class iterator_end { typedef ... value_type; ... iterator& operator++ () { throw ... } value_type operator* () { throw ... } bool operator== (const iterator& e) const { return e == *this; } } class iterator { typedef ... value_type; .. iterator& operator++ () { ... } value_type operator* () { ... } bool operator== (const iterator_end& e) const { return are_we_done_yet } } class statemachine { iterator begin() const { ... } iterator_end end() const { ... } } 我从来没有试过这个,所以我不能保证这会起作用.你的状态机的iterator和const_iterator typedef将指定一个与end()返回不同的类型,这可能会也可能不会引起麻烦. 另一种可能性是使用boost :: optional的pimpl变体.将迭代器状态放入一个单独的类中,并将其存储在迭代器中的boost :: optional中.保留为end()返回的迭代器设置的状态.您不会保存任何内存,但是您可以避免堆分配(boost :: optional不执行任何操作,它使用placement new!)和初始化开销. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |