类型说明符中的类型依赖嵌套名称说明符 [英] type-dependent nested-name-specifier in elaborated-type-specifier

查看:365
本文介绍了类型说明符中的类型依赖嵌套名称说明符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题之前,我从未在详细说明的类型说明符中看到嵌套名称说明符,而且最初扫视我认为它甚至没有被语法覆盖。现在我看到,从C ++ 98到现在,它被翻译为一个特殊的情况下,没有 typename-specifier 构造。 C ++ 11 7.1.6.3/2(C ++ 98中的7.1.5.3/2):


查找将在精细化类型说明符中继承标识符。如果标识符解析为 class-name 枚举名称,则 引入类型名的方式相同。


因此,看起来虽然你可以形成一个合格的阐述类型说明符,你需要注意,它从来不依赖于类型。在模板定义时,根据3.4.4的名称解析将永远不会找到类名,因为依赖名称假设是对象,除非前缀是 typename 关键字,



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



以此程式为例:

 模板< 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; }; //在定义时间正确
//实例化时通常出错
template<>
struct S2< short> :S1< {};

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 结构类型名称S :: I struct S< T> :: I 是明确的。



在模板实例化时, 4是清楚的: struct S1< int> :: I struct S2< int> :: I S2 是一个typedef,所以 struct S2 :: I 是一个错误。同时,在这一点上, S2 :: I 看起来不是typedef,而是结构,因此 struct S2 < ; short> :: I 是允许的。


I never saw a nested-name-specifier in an elaborated-type-specifier before this question, and at first glance I thought it wasn't even covered by the grammar. Now I see that since C++98 up to the present, it's translated as a special case without the typename-specifier construct. C++11 7.1.6.3/2 (7.1.5.3/2 in C++98):

3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name.

Therefore it would seem that although you can form a qualified elaborated-type-specifier, you need to take care that it's never type-dependent. Name resolution per 3.4.4 at template definition time will never find a class-name because dependent names are presumed to be objects unless prefixed with the typename keyword, which isn't grammatically allowed in this context.

Is this an accurate assessment of the meaning of the standard, and the design intent of the language?

解决方案

Expanding from the comments:

Take this program as an example:

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
}

At template definition time, both S2 and S3 are okay: 14.6p5 lists the exceptions where typename is not required. Essentially: where the use is unambiguous because the name can never be anything other than a type, typename is not required. This includes several cases where typename is not syntactically allowed, so where requiring typename would mean there is no way to write the program. Both typename struct S<T>::I and struct typename S<T>::I are hard errors, and struct S<T>::I is unambiguous.

At template instantiation time, the rules of 3.4.4 are clearer: both struct S1<int>::I and struct S2<int>::I can then be found, where it becomes apparent that S2<int>::I is a typedef, so struct S2<int>::I is an error. At the same time, at that point, S2<short>::I is seen not to be a typedef, but a struct, so struct S2<short>::I is allowed.

这篇关于类型说明符中的类型依赖嵌套名称说明符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆