> the idea that Widget& implies something different about the likelihood of modification compared with Widget* is quite foreign to me. this is precisely what Widget const & is for.
The issue is not ambiguity in the declaration, but rather the callsite: it's rarely possible to tell if a parameter is passed as a value, ref, or const ref at a particular callsite without consulting the function declaration. Oftentimes, one reads code without comparing each function call to its declaration, so it's easy to miss instances where objects are passed around by mutable ref rather than the more common const ref.
Using a pointer for the mutable cases resolves this ambiguity by forcing different syntax to be used at the callsite, which reminds:
* code authors that the parameter they're passing can be modified by the function call (they should think carefully about whether this is desired)
* code readers that a function call is potentially modifying its parameter (which can aid in debugging)
That's true; inside `hello_i_accept_pointers` there's no syntax at callsites to indicate that a mutable pointer is being passed. However, the variable being passed is of pointer type, which is readily apparent from the context of the function - the pointer parameter is declared in the same file, likely only lines above the callsite in question. This is still better than having to find the declaration of the called function, which is probably in a different file altogether.
But having it obvious at the call site means I don't even have to do that, dozens of times per day, every day.
It's something that's not easy to realize how useful it is until you actually do it. When working in a large codebase that consistently follows those rules it just makes code reading a breeze, it severely reduces the number of "context switches".
Obviously it's not the only way it can be done but it is a way and the benefits are significant.
The issue is not ambiguity in the declaration, but rather the callsite: it's rarely possible to tell if a parameter is passed as a value, ref, or const ref at a particular callsite without consulting the function declaration. Oftentimes, one reads code without comparing each function call to its declaration, so it's easy to miss instances where objects are passed around by mutable ref rather than the more common const ref.
Using a pointer for the mutable cases resolves this ambiguity by forcing different syntax to be used at the callsite, which reminds:
* code authors that the parameter they're passing can be modified by the function call (they should think carefully about whether this is desired)
* code readers that a function call is potentially modifying its parameter (which can aid in debugging)