依存型が基本クラスとして表示されるときにtypename
を追加する必要がないことを知って、私は非常に驚いています。
struct B {};
struct wr
{ typedef B type; };
template<class T>
struct A : T::type
{};
int main()
{
A<wr> a;
(void)a;
}
T::type
の前にtypename
が必要ないのはなぜですか?
他の人が指摘したように、それは特別なケースです。これに関する標準を引用するには:
[temp.res]
5 class-or-decltypeまたはelaborated-type-specifierで名前として使用される修飾名は、typenameキーワードを使用せずに、暗黙的に型に名前を付けるものと見なされます。テンプレートパラメータに依存するネストされた名前指定子がすぐに含まれるネストされた名前指定子では、typenameキーワードを使用せずに、識別子またはsimple-template-idが暗黙的に型に名前を付けると想定されます。 [注:typenameキーワードは、これらの構文の構文では許可されていません。 —メモ終了]
そしてC++ 20が来ると、typename
の必要性にはさらに多くの例外があります。
T::type
の前にtypename
が必要ないのはなぜですか?
値から継承できないからです。 typename
を使用して、指定されたネストされた識別子が型であることをコンパイラーに伝えますが、継承の場合はそれがとにかく当てはまる必要があるため、省略できます。そのため、言語はtypename
-ベース指定子のルール。 From cppreference (強調は私のもの):
依存名の
typename
曖昧性解消子エイリアステンプレートを含むテンプレートの宣言または定義では、現在のインスタンス化のメンバーではなく、テンプレートパラメーターに依存する名前は、キーワードtypenameが使用されているかそれがすでに型名として確立されていない限り、例えばtypedef宣言を使用するか、基本クラスに名前を付けるために使用されます。
typename
を省略できる場所が増えることに注意してください。 P0634 を参照してください。
typename
を使用する必要があるのは、コンパイラにタイプではなくタイプを期待するように指示する必要がある場合のみです。
継承できるのは型のみなので、あいまいさはなく、typename
は不要です。