テンプレートでc ++ 0x継承コンストラクタ
-
29-10-2019 - |
質問
これがクラスfooです: ジェネラコディセタグプレ
クラスバーは次のとおりです: ジェネラコディセタグプレ
コンストラクターを継承するための正しい構文ですか?「usingfoo :: foo;」を使用する場合その後、Visual C ++ 2010のコンパイラが停止します。 では、基本的に、VC ++ 2010のテンプレートクラスからコンストラクターを継承する方法は?
解決
これを正しく解析するには、template
の前にfoo<T>;
を挿入して、foo
がテンプレート名と見なされることをコンパイラーに通知する必要があります(foo<T>
は不明であるため、T
を調べてそれ自体を伝えることはできません)。ただし、::template
をusing宣言で使用することは許可されていません。この名前は、bar
のすべてのコンストラクターを指すわけではありません。代わりに、次のようなコンストラクターの特定のコンストラクター関数テンプレートの特殊化(T
はテンプレート引数です)を指します。
ジェネラコディセタグプレ
さらに、using宣言でtemplate-id
(foo<T>
など)を名前として使用することは無効です(これにより、関数テンプレートの特殊化を参照することは事実上禁止され、名前変換関数テンプレートの特殊化にも禁止が追加されます) )、したがって、::template
を使用して解析の問題を修正したとしても(可能であれば)、この時点でエラーが発生します。
継承されたコンストラクターが導入されたとき、構文規則を使用してコンストラクターを参照できるようにする特別な規則が追加されました。修飾ID(基本的には...::...
を使用した修飾名)があり、最後の修飾が最後のパーツ名の前にある場合特定のクラスの場合、次の2つの追加の方法でそのクラスのコンストラクターを指定できます。
- クラスにtemplate-id(
foo<T>
形式の名前)を使用して名前が付けられ、最後の部分がテンプレート名と一致する場合(つまり、foo<T>::foo
またはTTP<T>::TTP
とTTP
がテンプレートテンプレートパラメーター)。 - 最後の部分がクラス名と一致する場合(つまり、
foo::foo
またはT::T
、T
がテンプレートパラメーター)。これらの2つの追加ルールは、using宣言でのみアクティブになります。そして、それらは当然C ++ 03には存在しませんでした。 C ++ 03にも存在した他のルールは次のとおりです。最後の部分が注入されたクラス名に名前を付ける場合、この修飾名はコンストラクターも参照します:
-
foo::foo
はそのために機能します。ただし、このルールだけでは、T::T
にはT
というメンバーがないため、foo
(foo
はクラスT
を示します)は機能しません。そのため、特別なルールを設定して、書くことができます ジェネラコディセタグプレ
2番目も有効です。
foo
は、基本クラスのfoo<T>
に注入され、bar
に継承された注入されたクラス名です。その名前をbar::foo
で参照し、最後の部分であるfoo
を追加します。これは、挿入されたクラス名を再度参照して、 `fooのコンストラクターを示します。これで、試行した最初の名前がコンストラクター関数テンプレートの特殊化を参照する理由がわかりました(許可されている場合):
foo<T>::foo
部分がすべてのコンストラクターに名前を付け、その後に続く<T>
がフィルターで除外するためです。テンプレートを作成し、type引数を渡します。
-
他のヒント
コンパイラがコンストラクタの継承をまだサポートしていないが、可変個引数マクロ、可変個引数テンプレートと右辺値参照、および非常に便利なtype_traitをサポートしている場合は、次の回避策があります。 ジェネラコディセタグプレ
is_constructibleをまだ持っていない場合、基本的な考え方はそれがなくても機能しますが、「継承されたコンストラクター」は過度に貪欲になります。
2番目のテンプレートパラメータは必要ありません; ジェネラコディセタグプレ
すべきこと
編集これはg ++-4.4.1で機能することを撤回しますが、機能が利用可能になったときにこれが正しい構文になるはずです
他の回答は、C ++ 0xでコンストラクターを継承する方法を説明するのにすでに良い仕事をしています。ただし、この記事の執筆時点では、C ++ 0x機能セット全体を完全に実装しているコンパイラはありません。残念ながら、これはVC ++ 2010がコンストラクターの継承をまだサポートしていないことを意味します。
C ++ 0x標準はまだ公開されていません。標準の最終ドラフト
最新バージョンのGCCはコンストラクターの継承をサポートしていると思います。そのため、今すぐ試してみる必要がある場合は、それを使用できます。もちろん、C ++ 0xのサポートは実験的なものであり、バグが見つかった場合などに変更される可能性があります。