C++11 标准草案 N3337 在 [namespace.udecl]
中声明
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.
这通常用于在派生类中公开基类中的 protected 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-declarations 可以指定从属名称,并且 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 声明引入的名称也应该是依赖的,但是 [temp.dep]
没有明确提及依赖使用声明的情况。我错过了什么吗?
最佳答案
问题是 Type
不是一个类,而是一个类模板。您可以执行以下操作(这样您就可以告诉编译器 Type
是 B
范围内的类模板):
template<typename T>
struct B : A<T>
{
using A<T>::Type;
typedef typename B::template Type<int> IntType;
};
实际上,在您的第二个示例中,为了为 IntType
编写 typedef
,您必须执行相同的操作。
关于c++ - 具有从属限定标识的类成员 using-declaration 是否应该是从属名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27158750/