Step 4 of 7
Return by value is free
A common worry is that returning a big object from a function is slow, so people return pointers or fill in "out" parameters instead. In modern C++ that worry is outdated.
- Returning a temporary (
return Widget(...);): C++17 guarantees the object is built directly in the caller's variable. No copy and no move happen at all. This is called copy elision. - Returning a named local (
Widget w; ...; return w;): compilers almost always build it directly in place too (the "named return value optimization"). When they can't, the value is moved, not copied.
#include <iostream>
#include <string>
struct Loud {
std::string tag;
explicit Loud(std::string t) : tag(t) { std::cout << "construct " << tag << "\n"; }
Loud(const Loud& o) : tag(o.tag) { std::cout << "COPY " << tag << "\n"; }
};
Loud make_direct() {
return Loud("direct"); // guaranteed: built right in the caller
}
Loud make_named() {
Loud l("named");
l.tag += "!";
return l; // NRVO in practice
}
int main() {
Loud a = make_direct();
Loud b = make_named();
std::cout << a.tag << " " << b.tag << "\n";
Loud c = a; // a real copy, because we asked for one
}
construct direct
construct named
direct named!
COPY direct
Reading the output
- Each function constructs exactly once, and there's no
COPYline foraorb: the objects were built directly inmain's variables. - The only copy is
Loud c = a;, where copying is exactly what the code asks for, sinceais still alive.
What this means for your code
- Return by value. It's the clearest way to write a function that makes something, and it's cheap.
- Don't write
return std::move(local);. It prevents copy elision, forcing a move where there would have been nothing at all. Compilers warn about it (-Wpessimizing-move). - Returning a temporary directly, like
return Tracker(id);, is the case the language guarantees.
Your turn: the Tracker struct counts copies. Write Tracker make_tracker(int id) so that creating one via your function performs zero copies. The test prints the copy count.
Previous: Move assignment and the rule of five Next: Moved-from objects