【发布时间】:2014-02-22 09:57:55
【问题描述】:
在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 中为 identifier 进行名称查找。如果 identifier 解析为 class-name 或 enum-name,则 elaborated-type-specifier 会引入它以 simple-type-specifier 引入其 type-name 的相同方式进入声明。
因此,尽管您可以形成一个合格的详细类型说明符,但您需要注意它永远不会依赖于类型。 3.4.4 在模板定义时的名称解析永远不会找到类名,因为依赖名称被假定为对象,除非以 typename 关键字为前缀,这在此上下文中的语法上是不允许的。
这是对标准含义和语言设计意图的准确评估吗?
【问题讨论】:
-
我不明白为什么它是依赖于类型的,只要查找发生在实例化点。这就是 clang 实现的,这就是为什么它允许
struct S1<T>::I却将struct S2<T>::I诊断为 ideone.com/paV3Kh 中的错误(注意:ideone 使用 GCC,而 GCC 允许这样做,所以你看不到那里的错误)跨度> -
@hvd 有趣又奇怪;谢谢!但我真正想知道的是为什么不需要
typename关键字。实际上我还没有查找不需要的异常列表,所以我现在就去做…… -
好点。引用 14.6p2:“在模板声明或定义中使用且依赖于 template-parameter 的名称被假定为不命名类型,除非适用的名称查找找到类型名称或名称是由关键字
typename限定。”我也没有看到允许struct S1<T>::I的异常。 -
啊! 14.6p5:“在 mem-initializer-id、base-specifier 或 elaborated-type-specifier 中用作名称的限定名称i> 被隐式假定为命名一个类型,而不使用
typename关键字。在立即包含 nested-name-specifier 的 nested-name-specifier 中取决于模板参数,identifier 或 simple-template-id 被隐式假定为命名类型,而不使用typename关键字。"跨度>