私は解決しようとしているこのパズルを持っています。基本的には、次の例に要約されます。
template <typename CT>
struct A
{
typedef typename CT::VALUE_T FOO; // FOO is dependent on CT
};
template <typename CT>
struct B
{
typedef typename CT::BAR BAR;
BAR foo() {}
};
template <typename DT>
struct C : B<C<DT> >
{
typedef DT VALUE_T;
typedef typename A<C>::FOO BAR;
};
int main () {
C<int> c;
}
上記の説明を試みることはできますが (約 3 回試行してテキストを削除しました!)、基本的に要件は次のとおりです。
C
B
typed withC
(CRTP の利用)から継承する必要があります。つまり、B<C<>>
C
インスタンス化できる唯一のものですA
(つまりA
、で入力する必要がありますC
)A
は定義できる唯一のものですFOO
(FOO
はタイプに依存しCT
、関係は提示されたものよりも複雑です)
問題 (上記のコードでわかるように) は、BAR
型が 内でのみ使用可能であり、インスタンス化さC
れたときにこれが不完全であるため、テンプレート引数( )の型が表示されないことです。残念ながら 内では、型は関数への引数として使用され、型を返します (つまり、関数スコープに限定されないため、typedef を関数スコープに単純に移動することはできません)。B
B
BAR
CT
C<int>
B
BAR
これを回避する方法はありますか?上記の関係を壊すことはできません (最後の手段でない限り)。おそらくc ++ 11を使用すると、 typedefを使用auto
する必要性を回避できますが、これは現在のところまだオプションではありません。BAR
B
編集: @bitmasks のコメントに続き、さらに情報が追加されました。
- とのコードは
A
、B
さまざまな状況でかなりの数のバイナリで使用されています。この場合の唯一のユニークな状況は、C
から派生したものB
であり、他のインスタンスでは、 から派生したもののインスタンスをC
所有していますB
。 - テンプレート引数は、 および の既存の使用を変更する必要のない値にデフォルト設定できる限り、(およびで)
A
変更できます。同じタイプのセットが、デフォルトのテンプレート パラメーターとして、またはその他のメカニズムとして使用できる必要があります。B
A
B
ここでテンプレートを使用しているのは、密結合が必要であり、さまざまな状況でコードを使用できる柔軟性が必要だったからです。
コンポーネントの説明:
A
コンテナーとして説明するのが最も適切であり、FOO
実際には反復子です。含まれるものは、テンプレート パラメーターの typedef によって定義されます。B
のインスタンスが所有するいくつかのコンポーネントによって呼び出される一連の関数を含む基本クラスとして説明するのが最も適切ですC
。前のケースでは、これらのコンポーネントには から派生したものへの参照が渡されましたB
(そして、それらのものは によって所有されC
ています)。この例では、C
それ自体への参照を提供しています。
主な複雑さは、コンテナへのアクセスから発生します。以前はとA
の間の関係は のインスタンスを持っていましたが、現在は のインスタンスです- このセマンティクスの変更により、型がクラスに注入される方法が壊れます。B
C
C
B
C
B