有关提名数据成员为引用类型时类成员访问的问题 [英] A issue about the class member access while the nominated data member is of reference type

查看:65
本文介绍了有关提名数据成员为引用类型时类成员访问的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  #include< iostream> 
结构测试{
Test(int& r):rf(r){

}
int&射频
};
int main(){
int a = 0;
测试t(a);
decltype(t.rf)b;
}

考虑以上代码,编译器抱怨这样的代码是格式错误,因为 b 是引用类型,并且尚未初始化。但是根据以下规则,我想知道为什么 b 的类型是引用类型吗?

dcl.type.simple#4


对于表达式e,由decltype(e)表示的类型定义如下:



  • 如果e为命名结构化绑定([dcl.struct.bind])的未加括号的id表达式,decltype(e)是结构化绑定声明的规范中给出的引用类型;

  • 否则,如果e是未括号化的id表达式或未括号化的类成员访问权限,则decltype(e)是以e命名的实体的类型。如果没有这样的实体,或者如果e命名了一组重载函数,则程序的格式不正确;



expr。 ref#4 说:


如果E2被声明为,键入对T的引用 ,则E1。 E2是一个左值; E1.E2的类型为T 。否则,将应用以下规则之一。


这表示 t.rf 的类型是 int 。我不得不说,[expr.ref]部分没有说 E1.E2 仍然是一个引用(表达式<$ c的确切实体是什么) $ c> E1.E2 表示?)。只是说这样的表达式是 lvalue ,其类型就是引用所引用的类型。


我在[ expr],即:

expr#5


如果表达式最初的类型为对T的引用([dcl.ref],[dcl.init.ref]),则该类型在进行任何进一步的分析之前被调整为T 表达式指定引用所表示的对象或功能,根据表达式的不同,表达式可以是左值或x值。 [注意:在引用的生存期开始之前或结束之后,行为是不确定的(请参阅[basic.life])。 — end note]


这是否意味着在分析表达式 t.rf 之前,因为 rf 的类型为对T的引用,应将其调整为 int 并使用这样的表达式,即 rf 指定它所引用的 a


因此,根据上述规则, decltype(t.rf)的结果应为 int ,为什么编译器将其视为 int&

解决方案



如果E2被声明为对T的引用类型,则E1.E2为左值; E1.E2的类型为T。否则,将应用以下规则之一。


这意味着t.rf的类型为int。


实际上,这表示表达式 t.rf 是整数(类别是左值)。但是名为 entity 的类型(它是类成员)仍然是对int的左值引用,因此是 decltype(t.rf)


E2在上下文中的定义如下:


[expr.ref]


将postfix-expression.id-expression缩写为E1.E2,...


实体定义为:


[basic.pre]


实体是值,对象,引用,结构化绑定,函数,枚举数,类型,类成员,位域,模板,模板专业化,名称空间或包。


实体列表不包含表达式。 E2不是实体。这是一个命名(表示)实体的表达式。


#include <iostream>
struct Test{
    Test(int& r):rf(r){

    }
    int& rf;
};
int main(){
   int a = 0;
   Test t(a);
   decltype(t.rf) b;  
}

Consider the above code, the compiler complains such a code is ill-formed, because b is of reference type and it's not be initialized. However according to the following rules, I wonder why the type of b is a reference type?
dcl.type.simple#4

For an expression e, the type denoted by decltype(e) is defined as follows:

  • if e is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]), decltype(e) is the referenced type as given in the specification of the structured binding declaration;
  • otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;

And according to what the paragraph expr.ref#4 says:

If E2 is declared to have type "reference to T", then E1.E2 is an lvalue; the type of E1.E2 is T. Otherwise, one of the following rules applies.

It means that the type of t.rf is int. I have to say it is vague that the section [expr.ref] does not say, E1.E2 is still a reference(what is the exactly entity the expression E1.E2 denotes?). It just say such an expression is lvalue and its type is what the reference refer to.

I only find a special rule in [expr], that is:
expr#5

If an expression initially has the type "reference to T" ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. [ Note: Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see [basic.life]).  — end note ]

Does it mean that before analyzing the expression t.rf, since rf has the type "reference to T", it should be adjusted to int and such an expression, namely rf designates a to which it refers.

So, According to these above rules, the result of decltype(t.rf) should be int, why the compiler consider it as int&?

解决方案

if E2 is declared to have type "reference to T", then E1.E2 is an lvalue; the type of E1.E2 is T. Otherwise, one of the following rules applies.

It means that the type of t.rf is int.

Indeed, it means that the type of the expression t.rf is int (and category is lvalue). But the type of the named entity - which is the class member - is still lvalue reference to int and hence that is the type given by decltype(t.rf).

E2 is defined in the context as such:

[expr.ref]

Abbreviating postfix-expression.id-expression as E1.E2, ...

Entity is defined as:

[basic.pre]

An entity is a value, object, reference, structured binding, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or pack.

The list of entities doesn't include expressions. E2 is not an entity. It is an expression that names (denotes) an entity.

这篇关于有关提名数据成员为引用类型时类成员访问的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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