Since a reference (some-type&) behaves as a constant pointer (some-type * const), passing an argument via a "constant reference to pointer" parameter (some-type * const&) seems a bit redundant, because
- if the parameter is
some-type *- I'm copying it,
- I can't edit the original because I just don't handle it;
- if the parameter is
some-type * const&- I'm not copying it,
- I can't edit the orignal because I hold it as a
constentity.
So in some way the only difference between the two is that the former incurs a copy, whereas the latter doesn't.
In turn, this means that this difference can be relatively important for std::shared_ptrs, which can be bigger than raw pointers and std::unique_ptrs.
But is that (passing std::shared_ptrs by const& if they are "heavy") the only usecase for passing pointer arguments by const&?
As regards the observation that the pointer aspect of the question is unnecessary, I think that when talking of non pointer-like data types, it's kind of easy to see the biggest advantage (or one of the biggest advantages) of passing them by value vs by const&: in both cases you protect the actual entity at the call site, but in the latter you avoid copying a potentially huge object.
For pointer-like entities such as raw pointers and smart pointers, I look at them as things which are meant to be at least similar in size to each other, with the std::shared_ptr allowed to diverge from the similarity.
Anyway, if we are dealing with obviously small raw pointers and std::unique_ptrs and small std::shared_ptrs, so that we can consider the aforementioned advantage of passing by const& negligible, is there any other reason why I might want to pass them by const&?
Without a reference you cannot overload a function based on constness of the parameter:
But you can do so with a const/non-const reference: