At here,cppreference-lvalue,I found that
Cast expression to rvalue reference to function is lvalue.
I was curious, so I carried out the following experiment:
#include <iostream>
using namespace std;
typedef void (&&funr) (int);
typedef void (&funl) (int);
void test(int num){
cout<<num<<endl;//output:20
}
void foo(funr fun){
fun(10);
}
void foo(funl fun){
fun(20);//call this
}
template <typename T> void foo(T&& fun){
cout<<is_same<T,void(&)(int)>::value<<endl;//true, it is lvalue.
cout<<is_same<T,void(int)>::value<<endl;//false, it isn't rvalue.
}
int main()
{
foo(static_cast<void(&&)(int)>(test));
return 0;
}
the fact that so.
Why cast expression to rvalue reference to function is lvalue? Is it because a function type is no need to move semantics or something else? Or I understand this word wrong.
Cast expression to rvalue reference to function is lvalue
An lvalue is an expression that yields an object reference, such as a variable name, an array subscript reference, a dereferenced pointer, or a function call that returns a reference. An lvalue always has a defined region of storage, so you can take its address. An rvalue is an expression that is not an lvalue.
In the example, the main function passes an rvalue to f . The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g ). You can cast an lvalue to an rvalue reference.
An lvalue refers to an object that persists beyond a single expression. An rvalue is a temporary value that does not persist beyond the expression that uses it.
In this example, the rvalue reference a can be bound to the temporary initialized with the rvalue expression 2 , but the rvalue reference b cannot be bound to the lvalue expression i . You can bind the rvalue reference c to the temporary value 1.0 that is converted from the variable i . End of C++11 only.
It follows from the definition of value categories in C++11 3.10/1 (emphasis mine):
An lvalue (...) designates a function or an object. ...
An xvalue (an “eXpiring” value) also refers to an object, ...
An rvalue (...) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.
A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. ...
Notice that only the lvalue category can be a function, all the others are values or objects only.
It's also echoed in 5.2.9/1:
The result of the expression
static_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. ...
As for the why of it, I can of course only guess (not being part of the standardisation committee). But my guess is that it would make no sense to have rvalues of function type—a function can never be a temporary, it can never be at or near the end of its lifetime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With