C ++での不可分の相互の抽象化をコードにどのように?
-
21-08-2019 - |
質問
最初の例:
template <class HashingSolution>
struct State : public HashingSolution {
void Update(int idx, int val) {
UpdateHash(idx, val);
}
int GetState(int idx) {
return ...;
}
};
struct DummyHashingSolution {
void UpdateHash(int idx, int val) {}
void RecalcHash() {}
};
struct MyHashingSolution {
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, GetState(idx)); // Problem: no acces to GetState function, can't do recursive application of templates
...
}
};
この例では国はHashingSolutionのメソッドへのアクセス権を持っているので、私は国家クラスにMyHashingSolutionを渡すことができますが、HashingSolutionはGETSTATEを呼び出すことができません。この問題を回避することが可能ですか?
これは最も深いループです。ここでの仮想関数は、25%以上のパフォーマンスを低下します。 Inlineingは私にとって非常に重要です。
解決
、あなたはおそらく、<不思議経常テンプレートパターンのバリアントを使用したいです/>(CRTP)。それは、派生クラスでparametrisedクラステンプレートをMyHashingSolution
行い、次のとおりです。
template <typename D>
struct MyHashingSolution {
typedef D Derived;
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, derived().GetState(idx));
...
}
private:
// Just for convenience
Derived& derived() { return *static_cast<Derived*>(this); }
};
<:あなたは派生State
クラスは、テンプレートになりたいので、この場合は、あなたが取るのテンプレートテンプレートパラメータのをクラステンプレートとして宣言State
の少し変わったステップを取る必要があります/ P>
template <template <class T> class HashingSolution>
struct State : public HashingSolution<State<HashingSolution> > {
typedef HashingSolution<State<HashingSolution> > Parent;
void Update(int idx, int val) {
Parent::UpdateHash(idx, val); // g++ requires "Parent::"
}
int GetState(int idx) {
return ...;
}
};
キーポイントを提供State
がHashingSolution<State<HashingSolution> >
から継承する、ということであるDerived
でダウンキャストHashingSolution<State<HashingSolution> >
をコンパイルし、正常に動作するように、、static_cast<Derived*>(this)
はHashingSolution<State>::derived()
の派生クラスです。 (あなた台無しにし、代わりにState
からHashingSolution<SomeOtherType>
を導出し、その後derived()
の呼び出しを必要とする何かをしようとした場合static_cast<>
の要件が満たされていないと、コンパイラは文句を言うでしょう。)
そして、あなたがそうのように使用したい具体的なState
クラスを宣言します:
typedef State<MyHashingSolution> MyState;
残念ながら、このソリューションを使用すると、テンプレートのテンプレート引数としてそれらを使用できるようにするために、その1つのテンプレート引数を無視し、テンプレートにDummyHashingSolution
(および任意の他のそのようなタイプ)を変更する必要があります副作用があります。
他のヒント
暗闇の中でショットとして、(コメントを参照)、当該情報のほぼ完全な欠如を考慮:テンプレートが有用であろうか?彼らは多くの場合、コンパイル時のポリモーフィズムのために良いです。
これ以上の潜在的に有用な情報を得るには、より多くの問題を説明してください。問題のコメントを見てください。あなたはまだ基本的な設計に取り組んでいるとき、マイクロ最適化がなされる必要があるものを知っている理由を教えてください。コンパイルや実行環境についての非主流のものがあれば、私たちにいくつかの詳細を与えるます。