C++でPythonのようなジェネレータを実装する方法を知りたいですか? Pythonはキーワード "yield"を使用してこれを行うことができます。 しかし、C++でそれを行うには?C++でジェネレータを実装するにはどうしたらいいですか?
答えて
あなたは本当にそれをすることはできませんが、あなたはそれを偽造することができます。ここにはa way you can fake it in Cがあります。これはC++でも使用できます。
+1私が言うつもりだったのですが、実際に "欺く"と "実装する"の間には何の違いもありません。私は、C++では、ファンクタのメンバ変数のコルーチン状態にして、グローバルを使用してanakinのように名前付き関数を呼び出すのではなく、適切な場所で別のインスタンスを呼び出すことが望ましいと考えています。あなたはCで余分なパラメータを使って同様のことをすることができますが、そうしたいことはあまりありません。 –
コルーチンを複数回呼び出すと、異なる回答を得ることは、ある状態を保つことを意味します。状態を維持する方法はオブジェクトです。関数呼び出しのように見せる方法は、演算子のオーバーロードです。 http://en.wikipedia.org/wiki/Function_objectを参照してください。
C++には「イテレータ」があります。 1つは明示的にそれをインクリメントし、それを逆参照します。
標準ライブラリ関数で使用する場合は、ほとんどはstd::forward_iterator
から派生し、その関数の数を実装する必要があります。コレクションにkindofが発電機を模倣する
他の方法は、(利回り)を供給し、メンバ関数の引数としての機能を許可している機能にそれのすべての値:
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());
イテレータについて詳しく説明するために、実装:これは一例です。これは、ループ変数として、または標準アルゴリズムで使用できます。
#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;
}
あなたは(あなたがboost vaultからそれを取得する必要があります、まだ申し訳ありませんが、ないブースト分布上)boost.contextを使用することができます。
典型的な例のコードは次のようになります:
#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);
}
この...紳士...純粋BLACK MAGICです:私はそれを試してみた
http://www.codeproject.com/Articles/29524/Generators-in-C
、それ再帰的に動作します。私はそれ以来定期的に使用してきました。ジェネレータは、ほぼC++の一流の市民です。パフォーマンス上のオーバーヘッドはありません。
すぐに著者に深く感謝して
それは黒い魔法ではありません...しかし、それは非常にun-C++ 11-ishです。 – einpoklum
- 1. UIDocument.hを実装するにはどうしたらいいですか?
- 2. Iterableインターフェイスを実装するにはどうしたらいいですか?
- 3. CPythonでジェネレータとコルーチンがどのように実装されていますか?
- 4. Javaでapache reloadのようなものを実装するにはどうしたらいいですか?
- 5. カスタムコードブログ(C#で書かれた)にトラックバックを実装するにはどうすればいいですか?
- 6. PHPからファックスを実装するにはどうしたらいいですか?
- 7. 基本クラスから派生し、C#でインターフェイスを実装するにはどうすればよいですか?
- 8. SVGで消しゴム機能を実装するにはどうしたらいいですか?
- 9. アナログ音量計のようにメーターを実装するにはどうしたらいいですか?
- 10. ムース型形質の新しいハンドルを実装するにはどうしたらいいですか?
- 11. ASP.net ITemplateインターフェイスを実装するコントロールのカスタムコマンドを作成するにはどうしたらいいですか?
- 12. Gchatのようなポップアップを実装するにはどうしたらいいですか?
- 13. CMakeでSTL実装を設定するにはどうしたらいいですか?
- 14. PHPでOFファイルチューザを実装するにはどうしたらいいですか?
- 15. Flexでリンクのリストを実装するにはどうしたらいいですか?
- 16. Javaでマルチコアのアルゴリズムを実装するにはどうしたらいいですか?
- 17. iphoneゲームでマルチプレーヤーを実装するにはどうしたらいいですか?
- 18. 私のサイトでFacebook Chatを実装するにはどうしたらいいですか?
- 19. Log4JでBlazeDSの実装を設定するにはどうしたらいいですか?
- 20. LSMで私自身のフック機能を実装するにはどうしたらいいですか?
- 21. nodejs Stream APIを正しく実装するにはどうしたらいいですか?
- 22. これをワン・ライン・ジェネレータにするにはどうしたらいいですか?
- 23. レール3.0.9に読み込みスレーブ(mySql)を実装するにはどうしたらいいですか?
- 24. SQLiteデータベースとFMDBをアプリに実装するにはどうしたらいいですか?
- 25. 自分のチャットクライアントにXMPPプロトコルを実装するにはどうしたらいいですか?
- 26. ruby on railsにshow all comments機能を実装するにはどうしたらいいですか?
- 27. C#でトラックパッドにアクセスするにはどうしたらいいですか?
- 28. msiインストーラ(C#)からSQLスクリプトファイルを実行するにはどうしたらいいですか?
- 29. 実際にXcodeをアンインストールするにはどうしたらいいですか?
- 30. Gmailスタイルのラベルチューザを実装するにはどうしたらいいですか?
すぐに、私たちはC++ 20コルーチンを使って回答を追加することができます。 – xtofl