施放的结果是左值?

时间:2014-10-22 13:29:22

标签: c++ visual-c++ casting standards lvalue

int a = 0;

那么标准C ++中的(int)a rvalue 吗?

不同的编译器显示此代码的不同结果:

#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);
}

具有不同结果的编译器:

1)http://cpp.sh/2r6

2)http://webcompiler.cloudapp.net/

3 个答案:

答案 0 :(得分:10)

应该是 rvalue ,但 webcompiler 正在运行Visual Studio,Visual Studio有 extension which allows temporary objects to be bound to non-const lvalue references {{3}正如Igor在上面指出的那样,可以使用/Za a bug/extension that casues it to generate an lvalue in this case )禁用此功能。

我们可以看到它应该是草案C ++标准部分5.4 显式类型转换(演员表)中的 rvalue 特别是prvalue )符号) 1 表示(强调我的):

  

表达式(T)cast-expression的结果是T型   如果T是左值引用类型或右值,则结果是左值   如果T是右值引用,则引用函数类型和xvalue   对象类型; 否则结果是prvalue。 [注意:如果T是   如果是cv限定的非类型类型,则忽略cv限定符   在确定所得到的prvalue的类型时;见3.10。 -结束   注意]

see it livegcc都会产生 rvalue ,这是预期的结果。

顺便说一下,我建议使用clang而不是 webcompiler ,因为rextester允许您分享您的程序并进行实时共享。

更新

Ben Voigt指出这个rextester,因此似乎Visual Studio实际上产生了一个左值。所以这不仅仅是bug report

的情况

正如dyp也指出extension which allows temporary objects to be bound to non-const lvalue references

更新2

Mgetz提交了gcc used to have a cast to lvalue extension,回复是通过使用bug report来解决这个问题,该标志的说明如下:

  

指定/ Zc:rvalueCast选项时,编译器正确   将右值引用类型标识为强制转换操作的结果   按照C ++ 11标准。当选项不是时   指定,编译器行为与Visual Studio 2012中的相同。   默认情况下,/ Zc:rvalueCast已关闭。为了符合并消除   使用强制转换时出错,我们建议您使用/ Zc:rvalueCast。

目前还不清楚在将来的版本中是否会默认启用此标志。

答案 1 :(得分:4)

是的,对象类型的强制转换结果是 rvalue ,由C ++ 11 5.4 / 1指定:

  

如果T是左值参考,则结果为左值   如果T是对象类型的右值引用,则为函数类型和xvalue的类型或右值引用; 否则结果是prvalue

答案 2 :(得分:3)

在标准C ++中int(a)(int)a是rvalues(其他答案提供标准参考)。

您的代码示例正在利用MSVC中的错误/扩展,但不是乍看之下的错误/扩展。正如我们从这个在MSVC中运行的代码中看到的那样:

#include <iostream>

int main()
{
    int x = 0;
    (int)x = 1;
    std::cout << x << std::endl;
}

MSVC将(int)x视为左值。

即使MSVC有一个扩展,允许rvalues绑定到非const引用;该扩展仍然使rvalue引用比rvalues的左值引用更好。