Is pass-by-value a reasonable default in C++11?

It’s a reasonable default if you need to make a copy inside the body. This is what Dave Abrahams is advocating:

Guideline: Don’t copy your function arguments. Instead, pass them by value and let the compiler do the copying.

In code this means don’t do this:

void foo(T const& t)
{
    auto copy = t;
    // ...
}

but do this:

void foo(T t)
{
    // ...
}

which has the advantage that the caller can use foo like so:

T lval;
foo(lval); // copy from lvalue
foo(T {}); // (potential) move from prvalue
foo(std::move(lval)); // (potential) move from xvalue

and only minimal work is done. You’d need two overloads to do the same with references, void foo(T const&); and void foo(T&&);.

With that in mind, I now wrote my valued constructors as such:

class T {
    U u;
    V v;
public:
    T(U u, V v)
        : u(std::move(u))
        , v(std::move(v))
    {}
};

Otherwise, passing by reference to const still is reasonable.

Leave a Comment