1. Problem It Solves
std::move(source) does not transfer data anywhere by itself. It produces an xvalue, allowing overload resolution to select a move constructor or move assignment operator when one is available.
2. Prerequisites
Copy constructors
T(const T&)and move constructorsT(T&&).A named variable is an lvalue even when its declared type is
T&&.
3. Core Idea
std::move casts to an rvalue reference and preserves constness. The operation receiving its result determines whether resources are transferred.
In std::string destination = std::move(source), the string move constructor is selected. If source is a const std::string, the result is const std::string&&: it cannot bind to std::string&&, so ordinary string initialization copies instead.
4. Minimal Syntax
std::string source = "resource";
auto&& alias = std::move(source);
std::string destination = std::move(source);This needs <string> and <utility>. Creating alias only binds a reference to source; creating destination calls the move constructor.
5. How It Works
std::move(source)produces an xvalue that still refers tosource.The compiler selects among available constructors or assignment operators. It may select a move, select a copy, or reject the expression if no usable operation exists.
The selected operation handles resources. Moving an integer normally just copies its value; there is no owned allocation to transfer.
The source object still exists afterward. Standard library types such as
std::stringgenerally have a valid but unspecified state unless their API gives a stronger guarantee. User-defined types need their own contract. See the library's moved-from object rules.
6. Common Mistakes
Assuming
source.empty()must be true after moving a string.Calling
source.front()without checking that the string still has an element.Assuming
std::moveremovesconst, always beats copying, or always selects a move operation.Adding
std::movetoreturn local;by habit; this can prevent NRVO, which constructs a named local directly as the return result.
7. When to Use It
Use std::move when you permit the next operation to take an object's resources and no longer need its old value. For a template forwarding reference that must preserve the argument's value category, use std::forward<T> according to forwarding rules.
8. Simple Example
The C++20 sample constructs and prints the destination:
std::string source = "resource";
std::string destination = std::move(source);
std::cout << destination << '\n';It prints resource. The example makes no claim about the subsequent contents of source. You can assign source = "new value" to reuse it.
Complete sample code
Source file
dailycppinterview/058_move-move/main.cpp
// Real-World C++ Interviews Q058: What does std::move move?
// Key: `std::move` moves nothing by itself; it casts its argument to an xvalue so overload
// resolution may select a move operation. The selected operation determines what is transferred
// and the source's resulting state. Unless otherwise specified, moved-from standard-library
// objects are valid but have an unspecified state; user-defined types follow their own
// move-operation contract.
#include <iostream>
#include <string>
#include <utility>
int main() {
std::string source = "resource";
std::string destination = std::move(source);
std::cout << destination << '\n';
}
9. Key Takeaways
Separate the two steps: std::move changes how the expression is considered; the selected constructor or assignment operator performs the work. Read the type's contract before using the source afterward.
10. Self-Check Question
Full question: What does std::move move?
Why does auto&& alias = std::move(source) not transfer the string's contents? What changes if source is a const std::string? Can you promise that a moved-from string is empty?