Home > Article > Backend Development > How Does std::move() Handle Lvalues in C ?
What Does std::move() Do to lvalues?
std::move() is a powerful tool in C for facilitating perfect forwarding. Yet its implementation can raise a few eyebrows upon first glance. To clarify how std::move() achieves this, let's delve into the intricacies of its implementation.
Understanding the 'Move' Function
We'll start with the simplified version of the 'move' function template:
template <typename T> typename remove_reference<T>::type&& move(T&& arg) { return static_cast<typename remove_reference<T>::type&&>(arg); }
Case 1: Passing an Rvalue
When std::move() is called with an rvalue (a temporary object or an expression that evaluates to an rvalue), the move template is instantiated as follows:
// move with [T = Object]: remove_reference<Object>::type&& move(Object&& arg) { return static_cast<remove_reference<Object>::type&&>(arg); }
Since remove_reference
Object&& move(Object&& arg) { return static_cast<Object&&>(arg); }
As anticipated, the function simply casts its rvalue argument to an rvalue reference.
Case 2: Passing an Lvalue
Now, the interesting case arises when std::move() is invoked with an lvalue (a named variable or an expression that evaluates to an lvalue).
Object a; // a is lvalue Object b = std::move(a);
This time, the move template instantiates to:
// move with [T = Object&] remove_reference<Object&>::type&& move(Object& && arg) { return static_cast<remove_reference<Object&>::type&&>(arg); }
Again, remove_reference
Object&& move(Object& && arg) { return static_cast<Object&&>(arg); }
At first glance, this seems counterintuitive since we've passed an lvalue. However, C 11 introduces the concept of reference collapsing, which modifies the interpretation of reference syntax:
Under these rules, Object& && effectively behaves as Object&, an ordinary lvalue reference that can bind to lvalues.
Therefore, the final form of the function becomes:
Object&& move(Object& arg) { return static_cast<Object&&>(arg); }
In essence, std::move() casts the lvalue argument to an rvalue reference, enabling perfect forwarding regardless of the input type.
The above is the detailed content of How Does std::move() Handle Lvalues in C ?. For more information, please follow other related articles on the PHP Chinese website!