一般来说,解引用指针表达式的结果是引用类型吗?

Posted

技术标签:

【中文标题】一般来说,解引用指针表达式的结果是引用类型吗?【英文标题】:Generally, is dereference pointer expression results a reference type? 【发布时间】:2018-07-01 11:50:09 【问题描述】:

延迟指针导致间接使用对象的值。但我从来没有真正理解“使用”是什么意思。我开始思考这个问题,直到我的编译器为以下代码产生错误

int i = 0, *pi = &i;
decltype(*pi) c; // error: 'c' declared as reference but not initialized.

我看了很长时间的错误并搜索了一些问题我只能给出以下论点。不知道对不对。

论据 1:

1) *p 是一个不是变量(或非变量表达式)的表达式

2)解引用指针表达式产生一个引用,我们实际上是在使用引用来访问对象的值

论据 2:

只有decltype返回引用的解引用表达式,不是一般情况

请指出上述论点的任何不正确或不准确的描述。

【问题讨论】:

这是一种几乎总是可以让编译器告诉你表达式类型的技术:wandbox.org/permlink/GBApa0x01iwP7K9a(尝试访问不存在的成员) 在我看来,这是一个深入了解the standard 以获得答案的绝好机会(您在浏览它时可能还会学到一两件事)。 相关巫毒:***.com/questions/13202289/… 【参考方案1】:

Dereferencing a pointer yields an lvalue expression of the pointed-to type designating the object or function pointed to. 它不会产生引用。**piint 类型的左值。

decltype(这里有一个例外)报告表达式的类型及其值类别,the latter being encoded with reference types。因为*pi是一个左值,它被编码为一个左值引用类型,所以decltype(*pi)int &int是类型,&是值类别。

表达式永远不会有引用类型,因为任何引用都会被调整掉"prior to any further analysis"。


* 这不仅仅是技术上的区别:根据core issue 232 和core issue 453 的指导,您可以编写有效的解引用表达式,将其结果绑定到引用会导致未定义的行为。

【讨论】:

【参考方案2】:

回答你的标题问题:作为 T.C.也回答,没有。表达式永远没有引用类型。给定一个int a; int &b = a;,表达式a 和表达式b 都有int 类型,并且两个表达式都是左值。

1) *p 是一个不是变量(或非变量表达式)的表达式

正确。

2)解引用指针表达式产生一个引用,我们实际上是在使用引用来访问对象的值

解引用指针会得到一个左值,decltype 会变成左值引用。

仅 decltype 返回引用的解引用表达式,不是一般情况

我不完全确定你在这里的意思。如果您的意思是当 decltype 不产生引用时,声明 decltype(...) c; 没有初始化程序可能是有效的,那么是的,确实如此。如果您的意思是除了取消引用的指针之外,decltype 永远不会产生引用类型,那么不会。例如,

int a;
decltype((a)) b; // not okay - decltype((a)) is int & because (a) is not the name of the
                 // variable, and the expression (a) is an lvalue
decltype(a) c;   // okay - decltype(a) is int because a is the name of the variable
decltype(+a) d;  // okay - decltype(+a) is int because the +a is a prvalue of type int

【讨论】:

【参考方案3】:

事实上,标准在 8.5.2.1 中说明如下:

一元 * 运算符执行间接:它所指向的表达式 应用的应该是指向对象类型的指针,或指向 函数类型,结果是引用对象的左值或 表达式指向的函数。如果表达式的类型 是“指向T的指针”,结果的类型是“T”。

所以它不是引用,但decltype() 为您提供了实际上在 C++ 类型系统中具有表示的东西,并且引用是最接近它的东西。

【讨论】:

以上是关于一般来说,解引用指针表达式的结果是引用类型吗?的主要内容,如果未能解决你的问题,请参考以下文章

Rust Deref与自动解引用

5数组指针和引用:数组

Golang - 指针与引用

为啥取消引用称为取消引用的指针?

一初级篇——指针(*)取地址(&)解引用(*)与引用(&)的区别

c++11笔记