Skip to content

Instantly share code, notes, and snippets.

@plonk
Created April 23, 2013 22:16
Show Gist options
  • Select an option

  • Save plonk/5447882 to your computer and use it in GitHub Desktop.

Select an option

Save plonk/5447882 to your computer and use it in GitHub Desktop.
#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