[英]How can I implement a generator in C++?
我想知道如何在C ++中實現像Python這樣的生成器? Python可以使用關鍵字“yield”來執行此操作。 但是如何在C ++中實現呢?
在C ++中我們有'迭代器'。 一個明確要求一個interator,明確地遞增它並解除引用它。
如果希望它們與標准庫函數一起使用,它們應該主要從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() );
這......紳士......是純粹的黑魔法:
http://www.codeproject.com/Articles/29524/Generators-in-C
我已經嘗試過,它甚至可以遞歸地運行。 從那以后我一直在經常使用它。 生成器,幾乎是C ++中的一等公民。 甚至沒有任何性能開銷。
我對作者表示最深切的敬意
你真的不能這樣做,但你可以假裝它。 這是一種你可以在C中偽造它的方法 ,你也可以在C ++中使用它。
詳細說明迭代器實現:這是一個例子。 它可以用作循環變量,也可以用作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;
}
多次調用協程並獲得不同的答案意味着你保持一些狀態。 保持狀態的方式是對象。 使它們看起來像函數調用的方法是運算符重載。 見http://en.wikipedia.org/wiki/Function_object 。
你可以使用boost.context (對不起,還沒有在boost發布上,你必須從boost庫獲得它)。
典型的示例代碼如下:
#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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.