Let
int a = 0;
Then is (int)a
an rvalue in standard C++?
Different compilers show different results for this code:
#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);
}
compilers with different results:
The should be an rvalue but webcompiler is running Visual Studio and Visual Studio has an
extension which allows temporary objects to be bound to non-const lvalue references.a bug/extension that casues it to generate an lvalue in this case As Igor points out above this can be disabled using/Za
(see it live).We can see that it should be an rvalue(specifically a prvalue) from the draft C++ standard section
5.4
Explicit type conversion (cast notation) paragraph 1 which says (emphasis mine):Both gcc and clang result in rvalue which is the expected result.
As an aside, I would recommend using rextester over webcompiler since rextester allows you to share your program and also has live sharing.
Update
Ben Voigt point out this bug report and so it seems that Visual Studio actually produces an lvalue. So this is not simply a case of the extension which allows temporary objects to be bound to non-const lvalue references.
As dyp points out gcc used to have a cast to lvalue extension as well.
Update 2
Mgetz filed a bug report, the response was that this is fixed by using the /Zc:rvalueCast flag, the description of the flag is as follows:
It is unclear whether this flag will be enabled by default in future versions.
Yes, the result of a cast to an object type is an rvalue, as specified by C++11 5.4/1:
In Standard C++
int(a)
and(int)a
are rvalues (the other answers provide standard references).Your code example is exploiting a bug/extension in MSVC, but not what it seems like at first glance. As we can see from this code which works in MSVC:
MSVC treats
(int)x
as an lvalue.Even though MSVC has an extension to allow rvalues to bind to non-const references; that extension still makes rvalue references a better match than lvalue references for rvalues.