CRTPイディオムを使用して静的多型を使用し、実行時に使用する実装を選択できるようにします。私は例を見てみましょう:実行時に使用するCRTP実装を選択する
私はものを計算するための責任がいくつかのクラスがありますのは、それを呼びましょう、今、私は別のクラスのメンバーとして、これらのオブジェクトを使用したい
template<typename Implementation>
class FooInterface {
public:
void compute(){
(static_cast<Implementation*>(this))->compute();
}
};
class FooForward : public FooInterface<FooForward> {
public:
void compute(){
//do stuff
}
};
class FooBackward : public FooInterface<FooBackward> {
public:
void compute(){
//do other stuff
}
};
と
template<typename Implementation>
class BarInterface {
public:
void eval(){
(static_cast<Implementation*>(this))->eval();
}
};
class BarForward : public BarInterface<BarForward> {
public:
void eval(){
//do something
}
};
class BarBackward : public BarInterface<BarBackward> {
public:
void eval(){
//do something else
}
};
をModel
、およびループ内でそれらを使用する:
template<typename Foo, typename Bar>
class Model {
private:
Foo* foo_;
Bar* bar_;
int max_iter_;
public:
Model<Foo, Bar>(int max_iter) : max_iter_(max_iter){
foo_ = new Foo();
bar_ = new Bar();
}
void solve(){
for(int i = 0; i < max_iter_; ++i){
foo_->compute();
bar_->eval();
}
}
};
注意をFUNCTことイオンModel::solve()
は高い反復回数を実行し、アプリケーションでのパフォーマンスは非常に重要です。したがって、動的な多態性の代わりにCRTPを使用して、仮想関数呼び出しを回避し、コンパイラによる関数のインライン化を有効にします。
私の問題は、実行時にFooInterface
とBarInterface
のどちらの実装を使用するかをユーザーに決定させたいときに発生します。私のmain.cpp
では私が持っている:私は正しいModel
を返すことができますが、私は戻り値の型は何ができるか分からない、と私は想像する方法は、それが原因で便利ではありません工場の種類について考えている
int main(int argc, char** argv){
/*
* Here an input file is read into a map which looks like this
* std::map<std::string, std::string> settings
*/
// Here I need a way to choose, based on settings, what will Foo and Bar be
Model<Foo, Bar> model;
model.solve();
}
を私のアプリケーションでは、私は2つの以上のテンプレートパラメータを持って、その後、組み合わせの数は、私は物事を想像する方法非常に大きな
class Factory{
/*type?*/ createModel(std::map<std::string, std::string> settings){
if ((settings["foo"] == "fwd") && (settings["bar"] == "fwd")){
Model<FooForward, BarForward>* model = new Model<FooForward, BarForward>();
return model;
}
else if ((settings["foo"] == "fwd") && (settings["bar"] == "bwd")){
Model<FooForward, BarBackward>* model = new Model<FooForward, BarBackward>();
return model;
}
else if ((settings["foo"] == "bwd") && (settings["bar"] == "fwd")){
Model<FooBackward, BarForward>* model = new Model<FooBackward, BarForward>();
return model;
}
else {
Model<FooBackward, BarBackward>* model = new Model<FooBackward, BarBackward>();
return model;
}
}
};
となり、すべてのテンプレートの組み合わせがコンパイルされるだろうし、ユーザーが1つが使用する実行時に選択することができます。 CRTPを使ってこれを達成する方法はありますか?
ご回答ありがとうございます。私はこれを試してお知らせします。メンテナンス部分については、それは私が恐れていたものです。私は現在、 'Foo'と' Bar'では2つ以上の実装を持ち、 'Model'では2つ以上のメンバを持ち、可能な組み合わせの数を増やしています。ある種のテンプレートメタプログラミングがすべての組み合わせを処理するのに役立つと思うか、私のデザインを再考する方がいいですか? –