template <typename T>
struct bar: public foo<T>
{
using foo<T>::foo<T>;
};
これを正しく解析するには、template
の前に, を挿入して、テンプレート名と見なす必要があるfoo<T>;
ことをコンパイラに伝える必要があります ( は未知であるため、それ自体を調べることはできません)。ただし、using 宣言では using を使用できません。また、名前は のすべてのコンストラクターを参照するわけではありません。代わりに、次のようなコンストラクターの特定のコンストラクター関数テンプレートの特殊化 (はテンプレート引数) を参照します。foo
foo<T>
T
::template
bar
T
template<typename T>
foo();
さらに、 using 宣言がtemplate-id
(like foo<T>
) をその名前として使用することは有効ではありません (これは、関数テンプレートの特殊化を参照することを事実上禁止し、名前変換関数テンプレートの特殊化も禁止することを追加します)。を使用して解析の問題を修正して::template
も (可能であれば)、この時点でまだエラーが発生します。
継承されたコンストラクターが導入されたとき、構文規則を使用してコンストラクターを参照できるようにする特別な規則が追加されました...::...
。次に、そのクラスのコンストラクターを 2 つの追加の方法で示すことができます。
- クラスが template-id (フォームの名前
foo<T>
) を使用して命名され、最後の部分がテンプレート名と一致する場合 (そう、foo<T>::foo
またはテンプレート テンプレート パラメータである場合) TTP<T>::TTP
。TTP
- 最後の部分がクラス名と一致する場合 (so、
foo::foo
またはT::T
、T
テンプレート パラメーターである場合)。
これら 2 つの追加の規則は、using 宣言でのみ有効です。そして当然、それらは C++03 には存在しませんでした。C++03 にも存在していたもう 1 つの規則は、次のとおりです。最後の部分が注入されたクラス名を指定する場合、この修飾名もコンストラクターを参照します。
foo::foo
したがって、機能します。しかし、このルールだけでは、T::T
(ここでT
class を表すfoo
) は機能しません。foo
というメンバーが存在しないためT
です。
したがって、特別なルールを設定すると、次のように書くことができます
using foo<T>::foo;
using bar::foo::foo; // valid too
2 番目も有効です。foo
これは、基本クラスに注入されて にfoo<T>
継承された、注入されたクラス名bar
です。その名前を で参照し、注入されたクラス名を再度参照するbar::foo
最後の部分 を追加してfoo
、`foo のコンストラクターを示します。
これで、試した最初の名前がコンストラクター関数テンプレートの特殊化を参照する理由がわかりました (それが許可されている場合):foo<T>::foo
パーツはすべてのコンストラクターに名前を付け、<T>
その後に続く はテンプレートをフィルターで除外し、型を渡すためです。口論。