Подтвердить что ты не робот

Как я могу реализовать генератор в С++?

Я хочу знать, как реализовать генератор, например Python, на С++? Для этого Python может использовать ключевое слово "yield". Но как это сделать на С++?

4b9b3361

Ответ 1

В С++ у нас есть "итераторы". В одном явном виде запрашивается интернатор, явно увеличивает его и разыгрывает его.

Если вы хотите, чтобы они использовались со стандартными библиотечными функциями, они должны в основном выводиться из std::forward_iterator и реализовывать ряд его функций.

Другой способ подражать генератору в коллекции позволяет использовать функцию как аргумент для функции-члена, которая передает (выводит) все ее значения этой функции:

struct MyCollection {
    int values[30];

    template< typename F >  
    void generate( F& yield_function ) const {
       int* end = values+30; // make this better in your own code :)
       for( auto i: values ) yield_function( *i );
    }
};

// usage:
c.generate([](int i){ std::cout << i << std::endl; });

// or pre-C++11:
struct MyFunction { 
    void operator() (int i)const { printf( "%d\n", i); }
};
MyCollection c;
c.generate( MyFunction() );

Ответ 2

Это... Господа... чисто BLACK MAGIC:

http://www.codeproject.com/Articles/29524/Generators-in-C

Я пробовал, и он даже работает рекурсивно. Я использую его регулярно с тех пор. Генераторы, почти как первоклассные граждане на С++. Накладные расходы не начисляются.

С глубочайшим уважением автора

Ответ 4

Подробное описание реализации итератора: это пример. Он может использоваться как переменная цикла или в std-алгоритмах.

#include <iterator>

template< typename T, typename TDiff = T >
struct TGenerator : public std::iterator<std::forward_iterator_tag,T,TDiff> {
  T from,to;
  T value;
  TDiff step;
  bool issentinel;

  TGenerator( T from, T to, TDiff step, bool sentinel = false )
    : from(from),to(to),step(step),issentinel(sentinel), value(from)
  {}

  void operator++(){ value += step; }

  const T& operator*()const { return value; }

  bool operator!=( const TGenerator& other ) const {
    return value<to;
  }

  TGenerator sentinel()const { return TGenerator(0,0,0,true); }

};


#include <algorithm>
#include <iostream>

int main()
{
  TGenerator<int> i(0,10,3);
  std::copy( i, i.sentinel(), std::ostream_iterator<int>( std::cout, " " ) );

    return 0;
}

Ответ 5

Вызов сопрограммы несколько раз и получение разных ответов означает, что вы сохраняете какое-то состояние. Объектом является способ сохранения состояния. Способ сделать их похожими на вызов функции - перегрузка оператора. См. http://en.wikipedia.org/wiki/Function_object.

Ответ 6

вы можете использовать boost.context (извините, но не в форсированном дистрибутиве, вам придется получить его из boost vault).

Типичный пример кода будет таким:

#include <iostream>
#include <boost/context.hpp>

using namespace std;

struct Parameters {
  int par1;
  float par2;
};

boost::context c1;
boost::context c2;

void F(void* parameters) {
  Parameters& pars = *(Parameters*)parameters;
  cout << pars.par1 << endl;
  c2.jump_to(c1);
  cout << pars.par2 << endl;
};

int main() {
  c1 = boost::context::current();
  Parameters p;
  p.par1 = 8;
  c2 = boost::context::create_context( F , c1 , p );
  c1.jump_to(c2);
  p.par2 = 1.3;
  c1.jump_to(c2);
}