C++ 强制转换的结果是右值吗?
让C++ 强制转换的结果是右值吗?,c++,visual-c++,casting,standards,lvalue,C++,Visual C++,Casting,Standards,Lvalue,让 那么是(int)a < /Cord>标准C++中的rValue/< 不同的编译器对此代码显示不同的结果: int a = 0; #包括 使用名称空间std; 空f(int&x) { cout是的,根据C++11 5.4/1的规定,对对象类型进行强制转换的结果是一个右值: 如果T是左值引用,则结果为左值 类型或函数类型的右值引用,如果T是对象类型的右值引用,则为xvalue;否则结果为prvalue 应该是右值,但webcompiler正在运行Visual Studio,Visual Stu
那么是<代码>(int)a < /Cord>标准C++中的rValue/< 不同的编译器对此代码显示不同的结果:
int a = 0;
#包括
使用名称空间std;
空f(int&x)
{
cout是的,根据C++11 5.4/1的规定,对对象类型进行强制转换的结果是一个右值:
如果T
是左值引用,则结果为左值
类型或函数类型的右值引用,如果T是对象类型的右值引用,则为xvalue;否则结果为prvalue
应该是右值,但webcompiler正在运行Visual Studio,Visual Studio具有。正如Igor在上面指出的,可以使用/Za
()禁用此功能
我们可以看到它应该是从C++标准部分草案<代码> 5.4代码>显式转换(CAST符号)段落1(强调矿山):
表达式(T)强制转换表达式的结果为T类型
如果T是左值引用类型或右值,则结果为左值
如果T是右值引用,则引用函数类型和xvalue
到对象类型;否则结果为PR值。[注意:如果T为
对于cv限定的非类类型,将忽略cv限定符
确定结果PR值的类型时,请参见3.10.-结束
注]
和都会导致右值,这是预期的结果
另外,我建议您使用over webcompiler,因为rextester允许您共享您的程序,并且还可以进行实时共享
更新
Ben Voigt指出了这一点,所以看起来VisualStudio实际上产生了一个左值。所以这不仅仅是一个
正如dyp指出的那样
更新2
Mgetz提交了一份文件,答复是这是通过使用修复的,该标志的描述如下:
当指定/Zc:rvalueCast选项时,编译器将正确运行
将右值引用类型标识为强制转换操作的结果
根据C++11标准。当选项不可用时
指定时,编译器行为与Visual Studio 2012中的相同。
默认情况下,/Zc:rvalueCast处于禁用状态。为了一致性和消除
使用强制转换时出错,建议您使用/Zc:rvalecast
不清楚此标志是否在将来版本中启用,在标准C++ ++代码> int(a)< /> >和代码>(int)a < /C> >为rVals(其他答案提供标准引用)。
您的代码示例正在利用MSVC中的一个bug/扩展,但乍一看并不是这样。我们可以从这段在MSVC中工作的代码中看到:
#include <iostream>
using namespace std;
void f(int& x)
{
cout << "l value" << endl;
}
void f(int&& x)
{
cout << "r value" << endl;
}
int main()
{
int a = 0;
f((int)a);
}
#包括
int main()
{
int x=0;
(int)x=1;
std::cout关键是没有规则为从T
到T
的转换设置例外。有人检查过是否存在错误吗?粗略搜索没有发现错误。@Mgetz我正在查找,但没有发现任何明显的问题。相对于使用@ShafikYaghmour测试用例的VS2013,这是一个长期存在的“功能”允许临时绑定到非常量引用的MSVC。使用option将其关闭。MS最终作出响应,这显然是由他们控制的,他们已将我的错误标记为已修复。我仍在寻求澄清,是否在将来默认情况下打开此功能。+1供您推荐。live共享链接的使用寿命是多长?@MiNimuxEximu不确定,我只使用了短时间,TH站点没有文档。这个答案是错误的。实际上,VisualC++没有使用把LValk引用绑定到临时的错误特性……它完全不能创建一个临时的。参见Matt的回答,我的BUG报告绑定RoT T的语言扩展。o左值引用仅在存在对象的情况下有效;对于基本类型的prvalues则不是这样。奇怪的是,gcc曾经有一个类似的“扩展”,允许将强制转换的结果用作左值:(强制转换为左值)我只能假设(char)I=5;
比*((char*)&I)=5;
(在C中)。您可以在搜索“强制转换为左值”时找到一些讨论。例如,它似乎出现在早期C89草稿中。四年前,我在Connect上报告了这一点和其他几个变体:
#include <iostream>
int main()
{
int x = 0;
(int)x = 1;
std::cout << x << std::endl;
}