在this question之前,我从未见过精化类型说明符中的嵌套名称说明符,乍一看,我认为语法甚至没有涵盖它。现在我看到,自从C++98到现在,它被翻译成一个特例,没有类型名称说明符构造。C++11 7.1.6.3/2 (C++98为7.1.5.3/2):
3.4.4描述详细说明类型说明符中标识符的名称查找过程。如果标识符解析为类名或枚举名称,详细说明类型说明符将其导入声明中,就像简单类型说明符引入其类型名称一样。
因此,尽管您可以形成一个合格的精化类型说明符,但您需要注意它从来不依赖于类型。在模板定义时,每个3.4.4的名称解析都找不到类名,因为依赖的名称被假定为对象,除非以typename关键字作为前缀,这在语法上是不允许的。
这是对标准含义和语言设计意图的准确评估吗?
发布于 2014-02-22 10:46:32
从评论中扩展:
以这个计划为例:
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
}在模板定义时,S2和S3都可以: 14.6p5列出不需要typename的异常。本质上:如果使用是明确的,因为名称不能是类型以外的任何东西,则不需要typename。这包括几种情况,在语法上不允许使用typename,所以需要typename就意味着无法编写程序。typename struct S<T>::I和struct typename S<T>::I都是硬错误,struct S<T>::I是明确的。
在模板实例化时,3.4.4的规则更加清晰:然后可以找到struct S1<int>::I和struct S2<int>::I,其中很明显S2<int>::I是typedef,因此struct S2<int>::I是一个错误。同时,在这一点上,S2<short>::I被认为不是typedef,而是一个结构,因此允许使用struct S2<short>::I。
https://stackoverflow.com/questions/21952658
复制相似问题