C++11 標準のドラフト N3337 では、[namespace.udecl]
using 宣言は、using 宣言が現れる宣言領域に名前を導入します。
すべての using 宣言は宣言とメンバー宣言であるため、クラス定義で使用できます。
メンバー宣言として使用される using 宣言では、nested-name-specifier は、定義されているクラスの基本クラスに名前を付けるものとします。
これは通常、次の例のように、基本クラス内で保護された typedef を派生クラスで公開するために使用され、Clang の最新バージョンで正常にコンパイルされます。
struct A
{
protected:
typedef int Type;
};
struct B : A
{
using A::Type;
};
B::Type x;
using 宣言は、テンプレート クラスを参照できます。これはコンパイルされます:
struct A
{
protected:
template<typename T>
struct Type
{
};
};
struct B : A
{
using A::Type;
};
B::Type<int> x;
依存する基本クラスのテンプレートを参照することもできます。以下は正常にコンパイルされます (typedef がコメント化されています)。
template<typename T>
struct A
{
protected:
template<typename U>
struct Type
{
};
};
template<typename T>
struct B : A<T>
{
using /* typename */ A<T>::Type; // A<T> is dependent, typename required?
// typedef Type<int> IntType; // error: unknown type name 'Type'
};
B<int>::Type<int> x;
のコメントを外すtypename
と、インスタンス化時にエラーが発生しますB<int>
: 「エラー: 非型で使用される 'typename' キーワード」。
typedef のコメントを外すと、B
最初のインスタンス化の前に解析するときにエラーが発生します。Type
これは、コンパイラが依存型名として扱わないためだと思います。
の最後の段落は[namespace.udecl]
、using 宣言が依存する名前を指定する可能性があること、およびtypename
導入された名前のさらなる使用法を明確にするためにキーワードを使用する必要があることを示唆しています。
using-declaration がキーワード typename を使用し、従属名 (14.6.2) を指定する場合、using-declaration によって導入された名前は typedef-name として扱われます。
私の読書は、それが従属名であることを[temp.dep]
示唆しています。A<T>::Type
論理的には、using 宣言によって導入された名前も依存する必要がありますが[temp.dep]
、依存する using 宣言の場合については明示的に言及していません。何か不足していますか?