0

CRTP クラスの継承チェーンがあります。CRTP クラスは、「最終的な」派生クラスがそれ自体を CRTP パラメータとして渡し、継承チェーンを完成させるまで、互いに派生します。

template <class W>
struct Base
{
    .....
};
template <class W>
struct Derived_inheritable: public Base<W>
{
....
}

template <class W>
struct Derived2_inheritable: public Derived_inheritable<W>
{
....
}

...

私がやりたいことは、テンプレートを含まない CRTP 継承チェーンの各レベルで、そのような「最終的な」エンドユーザー クラスを持つことができるようにすることです。

typedef Derived1_inheritable<Derived1> Derived1;

ご想像のとおり、この typedef は機能しません。定義されている独自の型を参照しているためです。問題は、これをどのように達成するかです。私が考えることができる方法は、次のとおりです。

struct Derived1: public Derived1_inheritable<Derived1>
{
   //not convenient, need to redefine at least a forwarding constructor
}

コード内のコメントにあるように、これはあまり洗練されたソリューションではありません。コンストラクターを再定義して、基本コンストラクターに転送する必要があります。もっとエレガントな方法を知っている人はいますか?

4

2 に答える 2

1

typedef Derived1_inheritable Derived1;

その行は意味がありません。テンプレートへの引数は型ですが、テンプレートを渡そうとしています(ちなみに、インスタンス化するのと同じテンプレートですが、その余分な癖に加えて、テンプレートは引数としてを取り、非型を渡している)

あなたが何を達成しようとしているのかという質問からは、本当に明確ではありません。あなたはその目標を解決するためのあなたのアプローチではなく、あなたの目標を述べることに取り組むべきです。

テンプレートではなく、Wパラメーターとしてそれ自体を渡すDerivedX_inheritableごとに「最終」クラスを作成したいと思います。

これは、作成したコードで正確に実行されます。

struct Derived1: public Derived1_inheritable<Derived1> {}

これは型定義です(「final」クラスを作成します)。CRTPベースには、エンドユーザーが提供する必要のある引数が必要であり、その転送コンストラクターが必要であるという事実は、設計の単なる副作用です。

于 2012-04-17T13:12:52.057 に答える
0

私はエレガントな解決策を見つけたと思います:

template <class W>
struct Base
{
   .....
};
template <class W>
struct Derived_inheritable: public Base<W>
{
....
}

//solution
struct Derived2_dummy;

template <class W=derived2d_ummy>
struct Derived2_inheritable: public Derived_inheritable<W>
{
....
}
struct derived2_dummy: public: Derived_inheritable<>{};
typedef Derived2_inheritable<> Derived2;
于 2012-04-19T09:40:25.330 に答える