First, disclaimer:
shared_ptr not a panacea. It should be used when the property is actually shared. Ownership without separation is expressed by unique_ptr , and unique_ptr is expressed by reference (raw). weak_ptr for shared_ptr , which should be respected but not owned ... but is not a good defensive practice against legacy pointers in general. By default, shared_ptr goes directly to the lowest common denominator; this is bad programming practice.
The choice here is between shared_ptr< T > , shared_ptr< T const > , shared_ptr< T > const & and T const & and T & . Suppose you don't change anything, but a sequence can change its objects, so const desirable. This narrows it down to shared_ptr< T const > , shared_ptr< T > const & and T const & .
We reformulate the question as
Is shared_ptr< T > const & right choice?
In this light, evaluate the alternatives.
Weighing on the balance sheet, if ownership does not expand (for example, returning an object that stores an argument), you really need to pass a simple link. In this case, the function should rarely care about how its argument belongs. If it requires shared_ptr , breaks the separation of problems in the worst case. You cannot have a local object or a member subobject and still use this function. And worst of all, everything is more complicated.
If ownership potentially extends to someone else, which would justify using shared_ptr in the first place, then you should always pass the value shared_ptr< [const] T > . Yes, it copies shared_ptr on call. But the expensive part of copying shared_ptr updates the refcount, rather than pushing pointers to the stack. And if you give ownership, you still want to update it. Take the passed value and move , which does not concern refcount. By doing this, you will be left without any advantages and many disadvantages for passing by reference.
Potatoswatter
source share