When passing arguments to functions, consider the following table to decide how to pass variables.

cheap/impossible to copy cheap/moderate to move or don't know expensive to move
Out X f() f(X&)*
In/Out f(X&)
In f(X) f(const X&)
retain "copy"
  • Cheap or impossible to move, e.g., int, unique_ptr
  • Cheap to move, e.g., vector<T>, string
  • Moderate cost to move, e.g., array<vector>, BigPOD
  • Don’t know, unfamiliar type, template …
  • Expensive to move, e.g., BigPOD[], array<BigPOD>

*or return smart pointer at the cost of dynamic allocation

The table is taken from Herb Sutter’s talk “Back to the Basics!” at CppCon 2014.