Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rvalue or lvalue (const) reference parameter

I want to pass a parameter(s) (of some concrete type, say int) to the member function by r- or l- value (const) reference. My solution is:

#include <type_traits>
#include <utility>

struct F
{
    using desired_parameter_type = int;

    template< typename X, typename = typename std::enable_if< std::is_same< typename std::decay< X >::type, desired_parameter_type >::value >::type >
    void operator () (X && x) const
    {
        // or even static_assert(std::is_same< typename std::decay< X >::type, desired_parameter_type >::value, "");
        std::forward< X >(x); // something useful
    }
};

Another exaple is here http://pastebin.com/9kgHmsVC.

But it is too verbose. How to do it in a simpler way?

Maybe I should use the superposition of std::remove_reference and std::remove_const instead of std::decay, but there is just a simplification here.

like image 254
Tomilov Anatoliy Avatar asked May 04 '13 16:05

Tomilov Anatoliy


People also ask

Is const reference an lvalue?

Such a reference is called an lvalue reference to a const value (sometimes called a reference to const or a const reference). In the above program, we bind const reference ref to modifiable lvalue x . We can then use ref to access x , but because ref is const, we can not modify the value of x through ref .

What is the difference between lvalue and rvalue references?

“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable.

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.

Is an rvalue reference an rvalue?

An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.


1 Answers

If I understand your question correctly, you wish to have a single function whose parameter is either an rvalue reference (in case an rvalue is provided) or an lvalue reference to const (in case an lvalue is provided).

But what would this function do? Well, since it must be able to handle both cases, including the case where an lvalue is provided, it cannot modify its input (at least not the one bound to the x parameter) - if it did, it would violate the semantics of the const reference.

But then again, if it cannot alter the state of the parameter, there is no reason for allowing an rvalue reference: rather let x be an lvalue-reference to const all the time. lvalue references to const can bind to rvalues, so you will be allowed to pass both rvalues and lvalues.

If the semantics of the function is different based on what is passed, then I would say it makes more sense to write two such functions: one that takes an rvalue reference and one that takes an lvalue reference to const.

like image 184
Andy Prowl Avatar answered Oct 02 '22 00:10

Andy Prowl