std::move in C++
/ 3 min read
Table of Contents
Move semantics is one of those C++11 features that sounds scary but is actually pretty straightforward once you underestand it.
What std::move Actually Does
Here’s the thing that confused me for a long time: std::move doesn’t actually move anything. It’s just a cast. All it does is convert whatever you pass to it into an rvalue reference. The actual “moving” happens in the move constructor or move assignment operator of the object.
std::string original = "Hello";std::string moved = std::move(original); // std::move just casts to rvalue reference// The actual move happens in std::string's move constructorAfter this, original is in a valid but unspecified state. You can still call methods on it, but you shouldn’t assume what it contains.
Why This Matters
Think about a vector with a million elements. Without move semantcs, every time you returned it from a function or pass it around, you’d copy all million elements. With move semantics, you can just “steal” the internal pointer and leave the original object empty.
// Without move semantics - expensive copystd::vector<int> createBigVector() { std::vector<int> vec(1000000, 42); return vec; // expensive copy before C++11}
// With move semantics - just steal the resourcesstd::vector<int> createBigVector() { std::vector<int> vec(1000000, 42); return vec; // Compiler automatically uses move semantics}The compiler is actually smart enough to use move semantics automatically in many cases (like returning from functions), but sometimes you need std::move.
When I Actually Use std::move
Most of the time, I use std::move in these situations:
- Moving into containers: When I want to transfer ownership of an expensive object into a vector or other container:
std::vector<std::string> names;std::string long_name = "This is a very long text that I do not want to copy";names.push_back(std::move(long_name)); // Transfer ownership, no copy// long_name is now empty, but names[0] has the string!- In constructors and assignment operators: When implementing my own classes that manage resources:
class MyClass { std::vector<int> data_;public: MyClass(std::vector<int> data) : data_(std::move(data)) {} // Move the parameter into the member variable};- Swapping without copies: Though
std::swapalready does this internally:
std::string a = "first";std::string b = "second";std::string temp = std::move(a);a = std::move(b);b = std::move(temp);The Rule I Follow
I only use std::move when I’m done with an object and want to transfer its resources to something else. If I might need the object later, I don’t move it. Simple :)
The performance gains can be significant for big and expensive objects like containers, strings, or smart pointers. For simple types like integers, move and copy are identical, so it doesn’t matter.
One last thing: don’t std::move the return value from functions. The compiler already optimizes that case, and being explicit about it can actually prevent the optimization.