Step 5 of 7
Moved-from objects
After b = std::move(a);, what is a? For standard library types the rule is valid but unspecified:
- It's still a real object. You may destroy it, assign it a new value, or call functions with no preconditions, such as
clear(),empty()andsize(). - You must not rely on its value. A moved-from
std::stringorstd::vectoris usually empty, but the standard doesn't promise it.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
int main() {
std::vector<std::string> inbox = {"hi", "lunch?", "meeting at 3"};
std::vector<std::string> archive = std::move(inbox); // steal the whole buffer
inbox.clear(); // now definitely empty
std::cout << archive.size() << " archived, inbox " << inbox.size() << "\n";
inbox.push_back("new mail"); // reusing it is fine
std::cout << inbox[0] << "\n";
std::string draft = "unsent text";
archive.push_back(std::move(draft)); // move one element in
draft = "fresh draft"; // assign a new value: fine
std::cout << archive.back() << " / " << draft << "\n";
}
3 archived, inbox 0
new mail
unsent text / fresh draft
How it works
std::vector<std::string> archive = std::move(inbox);runs the vector's move constructor. It takes over the buffer, so none of the strings are copied, however many there are.inbox.clear()turns "unspecified" into "definitely empty", which is what the next user ofinboxexpects.- After
std::move(draft), assigning a new value is always allowed, and from then ondraftis fully usable again.
The professional habit
After moving from something, either stop using it or reset it explicitly (clear(), assignment). Code that reads a moved-from value may work today and break on another compiler.
A function can also move out of a reference parameter, as your task does. That's powerful but surprising for the caller, so name such functions clearly (take_all, release, drain), so readers know the argument will be emptied.
Your turn: write std::vector<std::string> take_all(std::vector<std::string>& src) that moves the whole contents out of src (no element copies) and leaves src definitely empty.
Previous: Return by value is free Next: Sink parameters and emplace_back