In the code below, is_rvalue_reference
returns true.
I would expect testRef(int &&)
to be called and not testRef(int &)
, but that's not the case (at least with my Visual Studio 2015 compiler).
Any idea of the reason why ?
void testRef( int&& i )
{
cout << "called testRef(int&&) " << endl;
}
void testRef( int& i )
{
cout << "called testRef(int&) " << endl;
}
int main()
{
int && rvalref = 4;
cout << "is rval? : " << std::is_rvalue_reference<decltype( rvalref )>() << endl;
testRef( rvalref );
}
Note that this is different from the question in Rvalue Reference is Treated as an Lvalue?
In that post they are talking about the variable inside the function: it's like asking whether in my example the variable i is an rvalue or an lvalue (the answer being that it is an lvalue in both cases, cause it has an address in both cases).
The whole point of having rvalues and std::move
, which is a cast to rvalue, is to allow to select the right overload in functions and constructors.
For example both the following cases resolve to a call to testRef(int && i)
:
int main()
{
int g = 3;
testRef(std::move(g));
testRef(4);
}
But with an rvalue reference it seems not to be the case.
rvalref
is an identifier for an object. An identifier for an object is always an lvalue.Expressions never have reference type. The expression
rvalref
has typeint
and value category "lvalue".In the declaration
int && rvalref
, the&&
describes howrvalref
will be initialized (i.e. by adding a new name to an object denoted by another expression, as opposed to creating a new object), and that's all.In an expression, the behaviour of the name of an object is the same, whether or not the name was the first name given to that object.
The code
decltype(identifier)
has special behaviour, compared todecltype(general_expression)
. It does not give the type and value category of an expression consisting of that identifier. The codedecltype((identifier))
would do that. Further reading