gpt4 book ai didi

c++ - 关于使用 operator reinterpret_cast 将引用类型转换为另一个的奇怪问题

转载 作者:行者123 更新时间:2023-12-04 01:08:59 25 4
gpt4 key购买 nike

#include <iostream>
int main(){
int& rf = reinterpret_cast<int&>((int&&)1);
}

在这个例子中,GCCMSVC不接受此代码。相反,Clang编译成功。结果是 here .

通过研究相关规则,对应的规则为:
expr.reinterpret.cast#11

A glvalue of type T1, designating an object x, can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_­cast. The result is that of *reinterpret_­cast<T2 *>(p) where p is a pointer to x of type “pointer to T1”. No temporary is created, no copy is made, and no constructors ([class.ctor]) or conversion functions ([class.conv]) are called.

看看这个规则,我觉得这个规则好模糊。它说结果是 *reinterpret_­cast<T2 *>(p) .取消引用指针的规则定义为:
expr.unary#op-1

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

所以,根据规则[expr.unary#op-1],*reinterpret_­cast<T2 *>(p)的值类别是左值。而规则[expr.reinterpret.cast#11]只要求源指针类型可以通过使用reinterpret_cast转换为目标指针类型。 ,其操作数没有其他要求,例如值类别。从这一点来说,我认为Clang给出了一个正确的过程。因为结果是左值,所以它可以绑定(bind)到左值引用。

现在,对第一个例子做一点修改

#include <iostream>
int main(){
int& rf = reinterpret_cast<int&>(1);
}

然后,three compilers都拒绝这个例子。这到底是怎么回事?与第一个示例的不同之处在于 reinterpret_cast 的操作数。这是纯右值。只是,这种差异使Clang不接受这个代码?根据expr#10

Whenever a prvalue expression appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion is applied to convert the expression to an xvalue.

如上述规则所述,临时物化转换 应应用于纯右值 1使它成为一个 glvalue。转换之后,我看不出这个例子和第一个例子有什么不同。为什么 Clang现在拒绝它?

让我们继续考虑第三个例子

#include <iostream>
int main(){
int&& rf = reinterpret_cast<int&&>(1);
}

这次GCC接受此示例,而其他两个编译器报告错误 result在这里。

如果将声明更改为int&& rf = reinterpret_cast<int&&>((int&&)1);然后Clang会接受的。

此外,[expr.reinterpret.cast#11] 已经说过使用 reinterpret_cast 将引用类型转换为另一种类型的结果。始终是一个左值 ( *reinterpret_­cast<T2 *>(p) ),它暗示我们不能使用右值引用类型来绑定(bind)到结果。不是吗?

这些例子是我在阅读 [expr.reinterpret.cast#11] 时想到的。不同的编译器给出非常不同的结果。有点奇怪。我还认为 [expr.reinterpret.cast#11] 的措辞非常模糊。当我们给出右值引用或左值引用类型时,它没有说操作数的值类别的要求。只是说只要这些指针类型都可以转换。该规则也没有说明结果是什么值类别。我们只能通过表达式*reinterpret_­cast<T2 *>(p)推断出它的值类别是左值.

如何解读这些问题。是 [expr.reinterpret.cast#11] 的缺陷吗?

最佳答案

So, according to the rule [expr.unary#op-1], the value category of *reinterpret_­cast<T2 *>(p) is lvalue.

不,因为[expr.reinterpret.cast]/11并没有说引用转换表达式在所有方面都等同于 *reinterpret_cast<T2*>(p) .它表示表达式的结果 与该表达式的相同。这里的“结果”是指[basic.lval]/5 :

The result of a glvalue is the entity denoted by the expression.

reinterpret_cast 的值类别表达式仅由 [expr.reinterpret.cast]/1 定义,

The result of the expression reinterpret_­cast<T>(v) is the result of converting the expression v to type T. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and ....

所以 reinterpret_cast<int&>((int&&)1)具有值类别左值,因为类型 int&是左值引用类型,不是因为一元*规则。其结果是由右值临时物化创建的对象 1 .

reinterpret_cast<int&>(1)... temporary materialization conversion should apply to prvalue 1 to make it be a glvalue

否 - [basic.reinterpret.cast] 中唯一可能描述 reinterpret_cast<int&&>(1) 的部分又会是paragraph 11 , 用于将 glvalue 转换为引用类型。但它的最后一句包括“没有创建临时文件”,所以临时物化是不允许的。

所以两者都是reinterpret_cast<int&>(1)reinterpret_cast<int&&>(1)格式错误,gcc 在接受 reinterpret_cast<int&&>(1) 时不正确没有任何错误或警告。

关于c++ - 关于使用 operator reinterpret_cast 将引用类型转换为另一个的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65424751/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com