- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
#include <iostream>
int main(){
int& rf = reinterpret_cast<int&>((int&&)1);
}
在这个例子中,GCC
和 MSVC
不接受此代码。相反,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 expressionv
to typeT
. IfT
is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; ifT
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 prvalue1
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/
我有这种来自 Google map 自动完成的奇怪行为(或者我可能错过了某事)...想法?奇怪的: 您在输入中输入某物,例如“伦敦” 您按 [ENTER] 你按下 [CLEAR] 按钮 你点击进入'输
这段代码与《Learning Java》(Oracle Press Books)一书中的代码完全一样,但它不起作用。我不明白为什么它不起作用,它应该起作用。我用 OpenJDK 和 Sun JDK 7
示例 1 中究竟发生了什么?这是如何解析的? # doesnt split on , [String]::Join(",",("aaaaa,aaaaa,aaaaa,aaaaa,aaaaa,aa
我需要获得方程式系统的解决方案。为此,我使用函数sgesv_()。 一切都很好,它使我感到解决方案的正确结果。 但是我得到一个奇怪的警告。 警告:从不兼容的指针类型传递'sgesv_'的参数3 我正在
我目前在制作动画时遇到一个奇怪的问题: [UIView animateWithDuration:3 delay:0
alert('works'); $(window).load(function () { alert('does not work'); });
我的代码: public class MyTest { public class StringSorter implements Comparator { public
我正在学习 JavaScript。尝试理解代码, function foo (){ var a = b = {name: 'Hai'}; document.write(a.name +''
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
这按预期工作: [dgorur@ted ~]$ env -i env [dgorur@ted ~]$ 这样做: [dgorur@ted ~]$ env -i which date which: no
struct BLA { int size_; int size()const{ return size_; } } int x; BLA b[ 2 ]; BLA * p = &b[
我有以下代码: #test img {vertical-align: middle;} div#test { border: 1px solid green; height: 150px; li
我想大多数使用过 C/C++ 的人都对预处理器的工作原理有一定的直觉(或多或少)。直到今天我也是这么认为的,但事实证明我的直觉是错误的。故事是这样的: 今天我尝试了一些东西,但我无法解释结果。首先考虑
我想为 TnSettings 做 mock,是的,如果通过以下方法编写代码,它就可以工作,问题是我们需要为每个案例编写 mock 代码,如果我们只 mock 一次然后执行多个案例,那么第二个将报告异常
我的项目中有以下两个结构 typedef volatile struct { unsigned char rx_buf[MAX_UART_BUF]; //Input buffer over U
Regex rx = new Regex(@"[+-]"); string[] substrings = rx.Split(expression); expression = "-9a3dcb
我的两个应用程序遇到了一个奇怪的问题。这是设置: 两个 tomcat/java 应用程序,在同一个网络中运行,连接到相同的 MS-SQL-Server。一个应用程序,恰好按顺序位于 DMZ 中可从互联
我目前正在与 Android Api Lvl 8 上的 OnLongClickListener 作斗争。 拿这段代码: this.webView.setOnLongClickListener(new
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
只是遇到了奇怪的事情。我有以下代码: -(void)ImageDownloadCompleat { [self performSelectorOnMainThread:@selector(up
我是一名优秀的程序员,十分优秀!