等效的C ++到Python生成器模式 [英] Equivalent C++ to Python generator pattern

查看:287
本文介绍了等效的C ++到Python生成器模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些示例Python代码,我需要在C ++中模仿。我不需要任何具体的解决方案(如基于协同程序的产出解决方案,虽然他们也是可以接受的答案),我只需要以某种方式重现语义。

I've got some example Python code that I need to mimic in C++. I do not require any specific solution (such as co-routine based yield solutions, although they would be acceptable answers as well), I simply need to reproduce the semantics in some manner.

这是一个基本的序列生成器,显然太大,无法存储实体化版本。

This is a basic sequence generator, clearly too large to store a materialized version.

def pair_sequence():
    for i in range(2**32):
        for j in range(2**32):
            yield (i, j)

目标是保持上面序列的两个实例,半锁步,但在块。在下面的示例中, first_pass 使用成对的序列来初始化缓冲区, second_pass

The goal is to maintain two instances of the sequence above, and iterate over them in semi-lockstep, but in chunks. In the example below the first_pass uses the sequence of pairs to initialize the buffer, and the second_pass regenerates the same exact sequence and processes the buffer again.

def run():
    seq1 = pair_sequence()
    seq2 = pair_sequence()

    buffer = [0] * 1000
    first_pass(seq1, buffer)
    second_pass(seq2, buffer)
    ... repeat ...



C ++



我可以找到一个解决方案在C ++中,只是模仿 yield 与C ++协程,但我没有找到任何有关如何做到这一点的好的参考。我也对这个问题的替代(非一般)解决方案感兴趣。我没有足够的内存预算来保存传递之间的序列副本。

C++

The only thing I can find for a solution in C++ is to mimic yield with C++ coroutines, but I haven't found any good reference on how to do this. I'm also interested in alternative (non general) solutions for this problem. I do not have enough memory budget to keep a copy of the sequence between passes.

推荐答案

生成器存在于C ++中, name: Input Iterators 。例如,从 std :: cin 读取类似于具有 char 的生成器。

Generators exist in C++, just under another name: Input Iterators. For example, reading from std::cin is similar to having a generator of char.

您只需要了解一个生成器的功能:

You simply need to understand what a generator does:


  • 有一个数据块:变量定义状态

  • 有一个init方法

  • 有一个下一个方法

  • 有一种信号终止方式。

  • there is a blob of data: the local variables define a state
  • there is an init method
  • there is a "next" method
  • there is a way to signal termination

在一个简单的例子中,概念上:

In your trivial example, it's easy enough. Conceptually:

struct State { unsigned i, j; };

State make();

void next(State&);

bool isDone(State const&);

当然,我们将其封装为一个合适的类:

Of course, we wrap this as a proper class:

class PairSequence {
  typedef void (PairSequence::*BoolLike)();
  void non_comparable();
public:
  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) {}

  // Safe Bool idiom
  operator BoolLike() const {
    return done ? nullptr : &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 ++比较繁琐:)

So hum yeah... might be that C++ is a tad more verbose :)

这篇关于等效的C ++到Python生成器模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆