Should a class-member using-declaration with a dependent qualified-id be a dependent name?
EDCOX1〔0〕中C++ 11标准状态的N33 37
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.
这通常用于使基类中的受保护typedef在派生类中成为公共的,如下面的示例所示,后者在最新版本的clang中成功编译:
1 2 3 4 5 6 7 8 9 10 11 12 | struct A { protected: typedef int Type; }; struct B : A { using A::Type; }; B::Type x; |
using声明可以引用模板类。编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | struct A { protected: template<typename T> struct Type { }; }; struct B : A { using A::Type; }; B::Type<int> x; |
也可以引用依赖基类中的模板。以下编译成功(typedef被注释)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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; |
取消对
取消对typedef的注释会在分析
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
我读到的
问题是
1 2 3 4 5 6 | template<typename T> struct B : A<T> { using A<T>::Type; typedef typename B::template Type<int> IntType; }; |
实际上,在您的第二个示例中,为了为
是的,使用具有从属限定ID的声明的类成员引入了从属名称。
[namespace.udecl]
A using-declaration introduces a name into the declarative region in which the using-declaration appears.
如果引入的名称是依赖的,它将保持依赖性——否则我找不到任何建议。
但是,using声明语法不提供指定依赖名称是模板的方法。在
下面的示例演示Dependent Using声明的有效用法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | template<typename T> struct A { protected: struct Type { typedef int M; }; }; template<typename T> struct B : A<T> { using typename A<T>::Type; typedef typename Type::M Type2; }; B<int>::Type2 x; |