一般的なアイデア:クラスのペア、ワーカーを作成するマネージャー。それぞれが、動作をカスタマイズする一連のポリシーを受け入れます。各ポリシーには、マネージャーに影響を与える部分 (いくつかのセットアップを行う) とワーカーに影響を与える部分 (ホスト ワーカー クラスの関数から呼び出す必要がある特定の作業関数を追加する - 現在は CRTP を介して行われます) があります。
ワーカーで使用されるポリシーは、常にマネージャーのポリシーを反映します。つまりmanager<foo,bar>
、タイプのワーカーを作成しますworker<foo_worker,bar_worker>
。このため、ワーカー ポリシーのタイプをマネージャー ポリシーに格納して、エンド ユーザーが両方を指定する必要がないようにしたいと考えています。
次のコードは、問題を示すコードの簡略化されたバージョンを実装しています。マネージャークラスのコメントを見てください。現在(例をコンパイルするために)、マネージャーはハードコーディングされたタイプのワーカーを作成しています。
質問:マネージャが独自のテンプレート パラメータに基づいて正しいワーカー クラスを決定/検索できるように、テンプレート クラス foo_worker のタイプをクラス foo 内に記録するにはどうすればよいですか?
typedef foo_worker work_policy;
class foo
foo_worker はクラス テンプレートではないため、inside ofは機能しません。さまざまな種類のラッパー クラスと、typename と template の組み合わせを試してみましたが、うまくいきませんでした。また、foo 内のネストされたクラスとして foo_worker を使用しようとしました。
回避できるのであれば、C++11 を必要としないことを望みますが、この問題が根本的に単純化されるのであれば、喜んで検討します。
この問題を回避するこのようなシステムを構築する別の方法はありますか?
よろしくお願いします=)
#include <iostream>
// Example policy1 "foo"
template <typename worker_type>
class foo_worker {
public:
void policy_work() {
std::cout << "foo_worker specific work" << std::endl;
static_cast<worker_type*>(this)->work_finish();
}
};
class foo {
public:
foo() {
std::cout << "foo setup" << std::endl;
}
};
// Example policy2 "bar"
template <typename worker_type>
class bar_worker {
public:
void policy_work() {
std::cout << "bar_worker specific work" << std::endl;
static_cast<worker_type*>(this)->work_finish();
}
};
class bar {
public:
bar() {
std::cout << "bar setup" << std::endl;
}
};
// worker class
template <template <class> class policy1,template <class> class policy2>
class worker
: public policy1< worker<policy1,policy2> >,
public policy2< worker<policy1,policy2> >
{
public:
typedef policy1< worker<policy1,policy2> > policy1_type;
typedef policy2< worker<policy1,policy2> > policy2_type;
void work() {
std::cout << "start work" << std::endl;
static_cast<policy1_type*>(this)->policy_work();
static_cast<policy2_type*>(this)->policy_work();
}
void work_finish() {
std::cout << "finish work" << std::endl;
}
};
// manager class
template <typename policy1,typename policy2>
class manager : public policy1, public policy2 {
public:
// this line hard codes workers to the foo_worker and bar_worker policy.
// I want to be able to look up which policies to send the worker based
// on the policies that was given to the manager.
typedef worker<bar_worker,foo_worker> worker_type;
// Would like to be able to do something like this instead:
//typedef worker<policy1::work_policy,policy2::work_policy> worker_type;
manager() : policy1(),policy2() {
std::cout << "manager setup" << std::endl;
}
worker_type* create() {
return new worker_type();
}
};
int main() {
manager<foo,bar> m;
manager<foo,bar>::worker_type* w = m.create();
w->work();
return 0;
}