Equivalent C++ to Python generator pattern

前端 未结 12 2380
Happy的楠姐
Happy的楠姐 2020-11-28 18:42

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 acce

12条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-28 19:12

    In C++ there are iterators, but implementing an iterator isn't straightforward: one has to consult the iterator concepts and carefully design the new iterator class to implement them. Thankfully, Boost has an iterator_facade template which should help implementing the iterators and iterator-compatible generators.

    Sometimes a stackless coroutine can be used to implement an iterator.

    P.S. See also this article which mentions both a switch hack by Christopher M. Kohlhoff and Boost.Coroutine by Oliver Kowalke. Oliver Kowalke's work is a followup on Boost.Coroutine by Giovanni P. Deretta.

    P.S. I think you can also write a kind of generator with lambdas:

    std::function generator = []{
      int i = 0;
      return [=]() mutable {
        return i < 10 ? i++ : -1;
      };
    }();
    int ret = 0; while ((ret = generator()) != -1) std::cout << "generator: " << ret << std::endl;
    

    Or with a functor:

    struct generator_t {
      int i = 0;
      int operator() () {
        return i < 10 ? i++ : -1;
      }
    } generator;
    int ret = 0; while ((ret = generator()) != -1) std::cout << "generator: " << ret << std::endl;
    

    P.S. Here's a generator implemented with the Mordor coroutines:

    #include 
    using std::cout; using std::endl;
    #include 
    using Mordor::Coroutine; using Mordor::Fiber;
    
    void testMordor() {
      Coroutine coro ([](Coroutine& self) {
        int i = 0; while (i < 9) self.yield (i++);
      });
      for (int i = coro.call(); coro.state() != Fiber::TERM; i = coro.call()) cout << i << endl;
    }
    

提交回复
热议问题