A using-declaration introduces a name into the declarative region in which the using-declaration appears.
Every using-declaration is a declaration and a member-declaration and so can be used in a class definition.
In a using-declaration used as a member-declaration,the nested-name-specifier shall name a base class of the
class being defined.
这通常用于在派生类的基类public中创建受保护的typedef,如下例所示,它在最新版本的Clang中成功编译:
struct A { protected: typedef int Type; }; struct B : A { using A::Type; }; B::Type x;
using-declaration可以引用模板类.这编译:
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;
在实例化B< int>:“error:’typename’关键字用于非类型时,取消注释typename会导致错误.
取消注释typedef会在首次实例化之前解析B时导致错误.我猜这是因为编译器不会将Type视为依赖类型名称.
[namespace.udecl]的最后一段建议using声明可以指定依赖名称,并且必须使用typename关键字以消除对引入的名称的进一步使用的歧义:
If a using-declaration uses the keyword typename and specifies a dependent name (14.6.2),the name introduced
by the using-declaration is treated as a typedef-name
我对[temp.dep]的解读表明A< T> :: Type是一个从属名称.从逻辑上讲,using-declaration引入的名称也应该是依赖的,但[temp.dep]没有明确提到依赖的using-declaration的情况.我错过了什么吗?
解决方法
template<typename T> struct B : A<T> { using A<T>::Type; typedef typename B::template Type<int> IntType; };
实际上,在你的第二个例子中,为了为IntType编写typedef,你必须做同样的事情.