std::move
cppreference std::move
std::move
is used to indicate that an object t
may be "moved from", i.e. allowing the efficient transfer of resources from t
to another object.
NOTE: 上面这段话中的“indicate”如何来理解?在 https://stackoverflow.com/a/11540204 中对此进行了回答:
Sometimes, we want to move from lvalues. That is, sometimes we want the compiler to treat an lvalue as if it were an rvalue, so it can invoke the move constructor, even though it could be potentially unsafe. For this purpose,
C++11
offers a standard library function template calledstd::move
inside the header<utility>
. This name is a bit unfortunate, becausestd::move
simply casts an lvalue to an rvalue; it does not move anything by itself. It merely enables moving. Maybe it should have been namedstd::cast_to_rvalue
orstd::enable_move
, but we are stuck with the name by now.
In particular, std::move
produces an xvalue expression that identifies its argument t
. It is exactly equivalent to a static_cast
to an rvalue reference type.
NOTE: 为什么
std::move
produces an xvalue expression ?这要如何来解释?1、入参是lvalue reference to an object,
std::move
的返回值是一个rvalue reference to an object,则此时compiler就可以选择move semantic function,在这些function中,可以将这个object给move走;显然,这个object满足两个条件:im
,所以它是一个xvalue2、入参是rvalue reference to an object,这种情况允许吗?是允许的,因为它的入参是forwarding reference;
Implementation
gcc/libstdc++-v3/include/bits/move.h
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);}
constexpr
说明它发生在compile-time;
Forwarding reference
一、入参:_Tp&& __t
,说明它使用了forwarding / universal reference,所以它的入参既可以是rvalue reference也可以是lvalue reference,关于这一点,在文章bajamircea std::move and std::forward中有描述:
First of all
std::move
is a template with aforwarding reference
argument which means that it can be called with either alvalue
or anrvalue
, and the reference collapsing rules apply.
二、关于 forwarding reference,参见 C++\CppReference\Functions\GP\Forwarding-reference&&perfect-forwarding
章节
三、"Forwarding reference"的实现,依赖于 "C++11-Reference collapsing折叠",参见 C++\CppReference\Reference\cppreference-Reference
章节
static_cast
cppreference static_cast conversion的3
专门对此进行了描述;
remove_reference
在文章bajamircea std::move and std::forward中有描述:
The
remove_reference
template specializations are used to get the underlying type forT
without any references, and that type is decorated with&&
for thestatic_cast
and return type.
在 https://stackoverflow.com/a/11540204 中,对std::move
的实现进行了分析。
std::move(some_lvalue)
casts an lvalue to an rvalue, thus enabling a subsequent move.
需要注意的是, 仅仅是rvalue,而不是prvalue,因为xvalue也是rvalue;
C++11
给予programmer可以引用prvalue的权利,这就是rvalue reference,对于prvalue,programmer是可以安全地将其move走的,这是在C++语言级别支持的(compiler能够识别)。同时C++还给予了programmer将一些**可以安全地移走的glvalue**也move走的权利,这些**可以安全地移走的glvalue**就是**xvalue**,显然,这些**可以安全地移走的glvalue**即具备 im 属性,所以它,为了支持这个,C++语言做了如下变动:
1、引入了xvalue的概念,xvalue既可以归入glvalue,也可以归入rvalue,通过std::move
,programmer告诉compiler将其当做rvalue来使用,以充分发挥move semantic
2、rvalue reference 安全地move prvalue
rvalue reference的syntax是&&
。
C++ std::move
does not move but enable move
1、bajamircea C++ std::move and std::forward:
C++
std::move
does not move andstd::forward
does not forward.
stackoverflow What are move semantics? # part two # Moving from lvalues
Sometimes, we want to move from lvalues. That is, sometimes we want the compiler to treat an lvalue as if it were an rvalue, so it can invoke the move constructor, even though it could be potentially unsafe. For this purpose,
C++11
offers a standard library function template calledstd::move
inside the header<utility>
. This name is a bit unfortunate, becausestd::move
simply casts an lvalue to an rvalue; it does not move anything by itself. It merely enables moving. Maybe it should have been namedstd::cast_to_rvalue
orstd::enable_move
, but we are stuck with the name by now.
Value category of std::move
stackoverflow What are move semantics? # part two # Xvalues
Note that even though
std::move(a)
is an rvalue, its evaluation does not create a temporary object. This conundrum(难题) forced the committee to introduce a third value category. Something that can be bound to an rvalue reference, even though it is not an rvalue in the traditional sense, is called an xvalue (eXpiring value). The traditional rvalues were renamed to prvalues (Pure rvalues).NOTE: eXpiring 的 含义是 “到期”,“eXpiring value”即“将亡值”。
TODO
stackoverflow What is std::move(), and when should it be used?