C++ view types: pass by const& or by value?

When in doubt, pass by value.

Now, you should only rarely be in doubt.

Often values are expensive to pass and give little benefit. Sometimes you actually want a reference to a possibly mutating value stored elsewhere. Often, in generic code, you don’t know if copying is an expensive operation, so you err on the side of not.

The reason why you should pass by value when in doubt is because values are easier to reason about. A reference (even a const one) to external data could mutate in the middle of an algorithm when you call a function callback or what have you, rendering what seems to be a simple function into a complex mess.

In this case, you already have an implicit reference bind (to the contents of the container you are viewing). Adding another implicit reference bind (to the view object that looks into the container) is no less bad because there are already complications.

Finally, compilers can reason about values better than they can about references to values. If you leave the locally analyzed scope (via a function pointer callback), the compiler has to presume the value stored in the const reference may have completely changed (if it cannot prove the contrary). A value in automatic storage with nobody taking a pointer to it can be assumed to not modify in a similar way — there is no defined way to access it and change it from an external scope, so such modifications can be presumed to not-happen.

Embrace the simplicity when you have an opportunity to pass a value as a value. It only happens rarely.

Leave a Comment