不思議なことに繰り返し発生するテンプレートパターンで読んだすべての資料は、継承の1つの層、つまりBase
とのように見えDerived : Base<Derived>
ます。さらに一歩進めたい場合はどうすればよいですか?
#include <iostream>
using std::cout;
template<typename LowestDerivedClass> class A {
public:
LowestDerivedClass& get() { return *static_cast<LowestDerivedClass*>(this); }
void print() { cout << "A\n"; }
};
template<typename LowestDerivedClass> class B : public A<LowestDerivedClass> {
public: void print() { cout << "B\n"; }
};
class C : public B<C> {
public: void print() { cout << "C\n"; }
};
int main()
{
C c;
c.get().print();
// B b; // Intentionally bad syntax,
// b.get().print(); // to demonstrate what I'm trying to accomplish
return 0;
}
このコードを書き直して、エラーなしでコンパイルして表示するにはどうすればよいですか?
C
B
c.get()。print()およびb.get()。print()を使用しますか?
動機:私が3つのクラスを持っていると仮定します、
class GuiElement { /* ... */ };
class Window : public GuiElement { /* ... */ };
class AlertBox : public Window { /* ... */ };
各クラスは、コンストラクターで6つほどのパラメーターを取ります。これらのパラメーターの多くはオプションであり、適切なデフォルト値があります。オプションのパラメータの面倒を避けるための最善の解決策は、名前付きパラメータイディオムを使用することです。
このイディオムの基本的な問題は、パラメータークラスの関数が呼び出されたオブジェクトを返さなければならないことですが、一部のパラメーターはGuiElementに、一部はWindowに、一部はAlertBoxに渡されます。これを書く方法が必要です:
AlertBox box = AlertBoxOptions()
.GuiElementParameter(1)
.WindowParameter(2)
.AlertBoxParameter(3)
.create();
ただし、たとえば、GuiElementParameter(int)はWindowParameter(int)関数を持たないGuiElementOptions&を返す可能性があるため、これはおそらく失敗します。
これは以前に尋ねられたものであり、解決策は不思議なことに繰り返されるテンプレートパターンのフレーバーのようです。私が使用する特定のフレーバーはここにあります。
ただし、新しいGui要素を作成するたびに記述するコードはたくさんあります。私はそれを単純化する方法を探していました。複雑さの主な原因は、CRTPを使用してNamed-Parameter-Idiomの問題を解決しているという事実ですが、2つではなく3つのレイヤー(GuiElement、Window、AlertBox)があり、現在の回避策では、クラスの数が4倍になっています。 。(!)たとえば、Window、WindowOptions、WindowBuilderT、およびWindowBuilder。
それは私の質問に私をもたらします。そこでは、GuiElement、Window、Alertboxなどの継承の長いチェーンでCRTPを使用するためのよりエレガントな方法を本質的に探しています。