Created
April 23, 2013 22:16
-
-
Save plonk/5447882 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <typeinfo> | |
| using namespace std; | |
| // コマンドオブジェクト、Job のインターフェース。 | |
| // これのポインタを使ってアクセスする。 | |
| class IJob { | |
| public: | |
| // インスタンス生成テンプレート関数。 | |
| // Job<L>型のインスタンスを new して返す。 | |
| template <class L> | |
| static IJob * new_job(L lambda); | |
| virtual void exec() = 0; // 実行メソッド | |
| virtual ~IJob() {}; // 具象クラスのインスタンスがデストラクトされるために。 | |
| }; | |
| // いろんな関数様オブジェクトを用いて作れるJobクラス。 | |
| template <class Lambda> | |
| class Job : public IJob { | |
| Lambda closure; | |
| public: | |
| // 初期化はできても代入はできない場合がある(closure = _closure;)) | |
| Job(Lambda _init) : closure(_init) { } | |
| void exec() { closure(); } | |
| ~Job() { | |
| cout << "dtor: " << typeid(this).name() << endl; | |
| } | |
| }; | |
| // 作成時に Job<...> の型名を書かずに済むように。 | |
| // また、ラムダ式は一度変数に代入しないと型が取れないので。 | |
| template <class L> | |
| IJob * IJob::new_job(L lambda) | |
| { | |
| return new Job<decltype(lambda)>(lambda); | |
| } | |
| // 昔ながらの関数 | |
| void func() | |
| { | |
| cout << ".\n"; | |
| } | |
| #include <memory> // for shared_ptr | |
| #include <vector> | |
| #include <string> | |
| void add_some_jobs(vector<shared_ptr<IJob>> &queue) | |
| { | |
| struct { | |
| void operator()() { cout << "Hello, ";} | |
| } functor; | |
| string str("World"); | |
| // 関数的なものを呼び出す Job を作って・・・ | |
| shared_ptr<IJob> j( IJob::new_job( functor ) ); // Hello, | |
| shared_ptr<IJob> k( IJob::new_job( [str] { cout << str; } ) ); // world | |
| shared_ptr<IJob> l( IJob::new_job( func ) ); // . | |
| // 突っ込む! | |
| queue.push_back(j); | |
| queue.push_back(k); | |
| queue.push_back(l); | |
| } | |
| int main() | |
| { | |
| vector<shared_ptr<IJob>> queue; | |
| add_some_jobs(queue); | |
| // 実行する。 | |
| #ifdef _MSC_VER | |
| for each (auto p in queue) | |
| p->exec(); | |
| #else | |
| // ポータブル。 | |
| for (auto i = queue.begin(); i != queue.end(); ++i) | |
| (*i)->exec(); | |
| #endif | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment