在elaborated-type-specifier中依赖于类型的嵌套名称说明符

时间:2014-02-22 09:57:56

标签: c++ templates

我在this question之前从未在详细说明类型说明符中看到嵌套名称说明符,乍一看我以为它甚至没有被语法覆盖。现在我看到,从C ++ 98到现在,它被翻译为没有 typename-specifier 构造的特殊情况。 C ++ 11 7.1.6.3/2(C ++ 98中的7.1.5.3/2):

  

3.4.4描述了如何在 elaborated-type-specifier 中对标识符进行名称查找。如果标识符解析为类名枚举名 elaborated-type-specifier 会引入它进入声明的方式与 simple-type-specifier 引入其类型名称的方式相同。

因此,虽然你可以形成一个合格的详细类型说明符,但你需要注意它从不依赖于类型。模板定义时每3.4.4的名称解析将永远不会找到类名,因为除非前缀为typename关键字,否则依赖名称将被假定为对象,在此上下文中不允许使用语法。

这是对标准含义和语言设计意图的准确评估吗?

1 个答案:

答案 0 :(得分:3)

从评论中扩展:

以此程序为例:

template <typename T>
struct S1 { struct I { }; };

template <typename T>
struct S2 { typedef struct S1<T>::I I; }; // okay

template <typename T>
struct S3 { typedef struct S2<T>::I I; }; // okay at definition time
                                          // usually error at instantiation time
template <>
struct S2<short> : S1<short> { };

int main() {
  S1<int>::I a;
  S2<int>::I &b = a; // okay
  S3<int>::I &c = b; // error
  S1<short>::I d;
  S2<short>::I &e = d; // okay
  S3<short>::I &f = e; // okay
}

在模板定义时,S2S3都可以:14.6p5列出了不需要typename的例外情况。基本上:使用是明确的,因为名称永远不能是类型,typename不是必需的。这包括在语法上不允许typename的几种情况,因此需要typename的情况意味着无法编写程序。 typename struct S<T>::Istruct typename S<T>::I都是硬错误,struct S<T>::I是明确的。

在模板实例化时,3.4.4的规则更清晰:然后可以找到struct S1<int>::Istruct S2<int>::I,显然S2<int>::I是typedef,所以{ {1}}是一个错误。同时,在此时,struct S2<int>::I被视为不是typedef,而是结构,因此允许S2<short>::I