Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why cast expression to rvalue reference to function is lvalue?

Tags:

c++

c++11

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

like image 204
Ron Tang Avatar asked Mar 18 '15 07:03

Ron Tang


People also ask

Is an rvalue reference an 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.

Can you pass an lvalue to an rvalue reference?

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.

What is the difference between an lvalue and an rvalue?

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.

Can rvalue bind to lvalue?

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.


1 Answers

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 expression v to type T. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T 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.

like image 67
Angew is no longer proud of SO Avatar answered Oct 04 '22 02:10

Angew is no longer proud of SO