【发布时间】:2015-01-25 08:20:33
【问题描述】:
[namespace.udecl] 中的 C++11 标准状态草案 N3337
using-declaration 将名称引入到 using-declaration 出现的声明区域中。
每个 using 声明都是一个声明和一个成员声明,因此可以在类定义中使用。
在用作成员声明的 using-declaration 中,nested-name-specifier 应命名 类被定义。
这通常用于在派生类中使基类中的受保护类型定义为公共,如下例所示,该示例在最新版本的 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;
在实例化 B<int> 时取消注释 typename 会导致错误:“error: 'typename' keyword used on a non-type”。
在第一次实例化之前解析 B 时,取消注释 typedef 会导致错误。我猜这是因为编译器没有将Type 视为依赖类型名称。
[namespace.udecl] 的最后一段建议 using-declarations 可以指定依赖名称,并且必须使用 typename 关键字来消除对引入名称的进一步使用的歧义:
如果 using-declaration 使用关键字 typename 并指定依赖名称 (14.6.2),则引入的名称 通过 using-declaration 被视为 typedef-name
我对@987654331@ 的阅读表明A<T>::Type 是一个从属名称。从逻辑上讲,使用声明引入的名称也应该是依赖的,但[temp.dep] 没有明确提到依赖使用声明的情况。我错过了什么吗?
【问题讨论】:
-
7.3.3p5: "using-declaration 不得命名 template-id"?
标签: c++ templates language-lawyer using-declaration dependent-name