How does std::move Transform Expressions into Rvalues?
std::move() facilitates the conversion of expressions into rvalues (right value references) to enable move semantics. However, the implementation in the MSVC standard library can be perplexing.
The implementation is as follows:
template<class _Ty> inline typename tr1::_Remove_reference<_Ty>::_Type&& move(_Ty&& _Arg) { // forward _Arg as movable return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg); }
Let's demonstrate how this works:
Object obj1; Object obj2 = std::move(obj1); // _Ty&& _Arg binds to obj1
Upon calling std::move(), the _Arg reference parameter binds to the lvalue obj1. However, since binding an rvalue reference to an lvalue is not directly allowed, one might expect a cast to an rvalue reference, such as (Object&&), to be required.
Delving further into the implementation of std::remove_reference clarifies matters:
template<class _Ty> struct _Remove_reference { // remove reference typedef _Ty _Type; }; template<class _Ty> struct _Remove_reference<_Ty&> { // remove reference typedef _Ty _Type; }; template<class _Ty> struct _Remove_reference<_Ty&&> { // remove rvalue reference typedef _Ty _Type; };
This implementation reveals that remove_reference transforms T& into T, T&& into T, and T&&& into T. Therefore, for our case, where obj1 is an lvalue of type Object, the resulting function becomes:
Object&& move(Object& arg) { return static_cast<Object&&>(arg); }
To elaborate further:
Object&& move(Object&& arg) { return static_cast<Object&&>(arg); }
The cast to Object&& is necessary because named rvalue references are treated as lvalues, while implicit conversion from lvalue to rvalue reference is disallowed.
Object&& move(Object& && arg) { return static_cast<Object&&>(arg); }
Here, C 11's reference collapsing rules come into play and allow the expression Object& && to be interpreted as Object&, an lvalue reference, which can indeed bind to lvalues. Thus, the final function transforms its argument into an rvalue reference and returns it.
In conclusion, std::move() utilizes std::remove_reference to enable the transformation of both lvalues and rvalues into rvalues, facilitating move semantics in C .
The above is the detailed content of How does `std::move()` achieve the conversion of lvalues to rvalues in C ?. For more information, please follow other related articles on the PHP Chinese website!