Skip to content

Last updated:2026-10-12

How C++ std::move Works and How to Use It

std::move is a very important function: it provides a way to mark an lvalue object as a special kind of rvalue object, namely an xvalue. This transformation is what allows move semantics to be applied instead of the usual copy semantics.

  • Why use std::move
  • Practical use cases

1.Why use std::move

Normally, only rvalue objects can be moved, because the move constructor takes an rvalue reference as its parameter, and an rvalue reference can only bind to an rvalue. Therefore, if you want to perform a move operation on an object represented by an lvalue expression, you need to use std::move to convert it into an xvalue (a special kind of rvalue).

Use std::move with care, because a move operation leaves the object in a state where typically only destruction is allowed. Therefore, it is best to move an object only at its last use.

std::move does not actually perform a move. To be clear, std::move does not execute the move operation itself. It merely converts the given lvalue object into an rvalue reference. Here is one possible implementation of std::move:

template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
    return static_cast<typename remove_reference<T>::type&&>(t);
}

2.Practical use cases

2.1 Move construction instead of copy construction

In the function f1, the parameter a is an lvalue that has an rvalue reference type, not an rvalue itself, because it has a name. Therefore, to force the move constructor of Foo to be invoked, we must convert it into an rvalue, and std::move does exactly that.

struct Foo { 
    ... 
    Foo(const Foo&) {} 
    Foo(Foo&&) {} 
}; 

void f1(Foo&& a) { 
    Foo b(a); // 调用拷贝构造函数,而非移动构造函数
} 

void f2(Foo&& a) { 
    Foo b(std::move(a)); // right
} 

2.2 Ownership management

Suppose we have the following code:

Foo* p = new Foo();
data.push_back(p);

The code above works, but you cannot tell who owns the pointer. Who should delete the pointer? And when should the pointer be deleted? Will it be deleted when the container is destroyed?

In C++11, the statement std::unique_ptr<Foo> p(new Foo()); produces a compilation error. The reason is that the unique ownership rule kicks in.

However, you can use std::move to transfer ownership of the pointer:

data.push_back(std::move(p));

Now ownership of the pointer has been transferred to the container, and it will be deleted when the lifetime of the container ends. Although the object p still exists, any attempt to dereference it will result in a null pointer exception.

In fact, after the move operation, the internal pointer held by p has been set to nullptr.

In summary, the purpose of std::move is to provide a means of safely enabling move semantics for objects, converting their lvalue nature into an rvalue so that they can be consumed by move constructors or the move assignment operator. Using std::move correctly can improve performance and ensure proper ownership transfer.

So the next question is: when do you not need to use std::move?

Comments