Step 1 of 7
Copies are expensive
Copying a std::vector with a million elements copies a million elements. That's fine when you need two independent vectors. But very often the source is about to disappear anyway: it's a temporary, or a variable you'll never use again. Copying it and then throwing the original away is wasted work.
A move avoids that. Instead of copying the elements, the new vector simply takes over the old one's heap buffer (a pointer, a size and a capacity: three small values), and the old vector is left empty. It's like handing someone your suitcase instead of packing an identical one for them.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
int main() {
std::string a = "a long string that lives on the heap, not in the small buffer";
std::string copy = a; // copies every character
std::string moved = std::move(a); // takes a's buffer
std::cout << copy.size() << " " << moved.size() << "\n";
std::cout << (copy == moved) << "\n";
std::vector<std::string> shelf;
std::string book = "Dune";
shelf.push_back(book); // copy: we still use book below
shelf.push_back(std::move(copy)); // move: done with copy
std::cout << book << " | " << shelf.size() << "\n";
}
61 61
1
Dune | 2
lvalues and rvalues
C++ decides between copying and moving by looking at the kind of expression:
- An lvalue has a name and lives on after this line:
a,book,v[0]. Stealing from it would surprise you later, so C++ copies. - An rvalue is a temporary about to die:
make_vector(),a + b, a number like42. Nobody can use it again, so C++ moves from it automatically.
What std::move really does
std::move(x) doesn't move anything by itself. It's a cast that turns x into an rvalue, which means "I'm done with x, you may steal from it". The actual moving is done by whatever receives it: the vector's push_back, a constructor, an assignment.
After a move, the source is in a valid but unspecified state. Don't read its value. You may assign it a new one or let it be destroyed.
Your turn: move big into store instead of copying it.