In traditional C++, passing by value into functions and methods is slow for large objects, and is generally frowned upon. Instead, C++ programmers tend to pass references around, which is faster, but which introduces all sorts of complicated questions around ownership and especially around memory management (in the event that the object is heap-allocated)
Now, in C++11, we have Rvalue references and move constructors, which mean that it's possible to implement a large object (like an std::vector
) that's cheap to pass by value into and out of a function.
So, does this mean that the default should be to pass by value for instances of types such as std::vector
and std::string
? What about for custom objects? What's the new best practice?
In almost all cases, your semantics should be either:
All other signatures should be used only sparingly, and with good justification. The compiler will now pretty much always work these out in the most efficient way. You can just get on with writing your code!
Pass parameters by value if inside the function body you need a copy of the object or only need to move the object. Pass by
const&
if you only need non-mutating access to the object.Object copy example:
Object move example:
Non-mutating access example:
For rationale, see these blog posts by Dave Abrahams and Xiang Fan.
It's a reasonable default if you need to make a copy inside the body. This is what Dave Abrahams is advocating:
In code this means don't do this:
but do this:
which has the advantage that the caller can use
foo
like so:and only minimal work is done. You'd need two overloads to do the same with references,
void foo(T const&);
andvoid foo(T&&);
.With that in mind, I now wrote my valued constructors as such:
Otherwise, passing by reference to
const
still is reasonable.