我有一些需要在C++中模仿的示例Python代码。我不需要任何特定的解决方案(例如基于协同例程的收益解决方案,尽管它们也是可接受的答案),我只需要以某种方式重现语义即可。
这是一个基本的序列生成器,显然太大了,无法存储实例化版本。
def pair_sequence(): for i in range(2**32): for j in range(2**32): yield (i, j)
目标是维护上述序列的两个实例,并以半锁步的方式在块上进行迭代。在下面的示例中,first_pass使用对的序列来初始化缓冲区,然后second_pass重新生成 相同的精确序列 并再次处理缓冲区。
first_pass
second_pass
def run(): seq1 = pair_sequence() seq2 = pair_sequence() buffer = [0] * 1000 first_pass(seq1, buffer) second_pass(seq2, buffer) ... repeat ...
对于C 解决方案,我唯一能找到的就是模仿yieldC 协程,但是我还没有找到有关如何执行此操作的良好参考。我也对这个问题的替代(非一般)解决方案感兴趣。我没有足够的内存预算来保留两次通过之间的序列副本。
yield
生成器在C ++中存在,只是另一个名称: Input Iterators 。例如,从读取std::cin类似于使用的生成器char。
std::cin
char
您只需要了解生成器的功能:
在您的琐碎示例中,这很容易。从概念上讲:
struct State { unsigned i, j; }; State make(); void next(State&); bool isDone(State const&);
当然,我们将其包装为适当的类:
class PairSequence: // (implicit aliases) public std::iterator< std::input_iterator_tag, std::pair<unsigned, unsigned> > { // C++03 typedef void (PairSequence::*BoolLike)(); void non_comparable(); public: // C++11 (explicit aliases) using iterator_category = std::input_iterator_tag; using value_type = std::pair<unsigned, unsigned>; using reference = value_type const&; using pointer = value_type const*; using difference_type = ptrdiff_t; // C++03 (explicit aliases) typedef std::input_iterator_tag iterator_category; typedef std::pair<unsigned, unsigned> value_type; typedef value_type const& reference; typedef value_type const* pointer; typedef ptrdiff_t difference_type; PairSequence(): done(false) {} // C++11 explicit operator bool() const { return !done; } // C++03 // Safe Bool idiom operator BoolLike() const { return done ? 0 : &PairSequence::non_comparable; } reference operator*() const { return ij; } pointer operator->() const { return &ij; } PairSequence& operator++() { static unsigned const Max = std::numeric_limts<unsigned>::max(); assert(!done); if (ij.second != Max) { ++ij.second; return *this; } if (ij.first != Max) { ij.second = 0; ++ij.first; return *this; } done = true; return *this; } PairSequence operator++(int) { PairSequence const tmp(*this); ++*this; return tmp; } private: bool done; value_type ij; };
所以,嗯…可能是C ++有点冗长:)