C/C++ Arena

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.

#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

What this means for your code

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