As far as the C++ standard library is concerned, there are two distinct cases, based on the answer to one question: are you accessing an object or manipulating an object's property?
Accessing the contents of a container is accessing a conceptual subobject of the container. This is usually done via an overloaded function that returns a reference to the object. That reference will be const
or non-const
based on whether the container is const
or not. This is true whether you're talking about std::get<tuple>
, std::optional::value
, or std::vector::at
.
For manipulating properties of an object, this is typically done via return values/parameters. It's still using an overloaded function; one overload takes no parameters at all, while the other overload takes the value to set the property to. The latter is not const
, and in many cases both will return the (pre-modification) value.
Iterators are an interesting intersection. Most iterators return references to objects in their containers. But the Input/OutputIterator distinction makes it possible for input iterators to generate values that aren't part of some container. Their operator*
could return a value rather than a reference to an object.
Similarly, output iterators often have their operator*
return a proxy-object which behaves like a reference. This proxy uses the assignment operator to set the value into the output stream, without having to return an actual value of that type.
But in virtually all cases in the standard library, you have one function name with multiple overloads based on the const
-ness of the source object.
The most prominent case of the standard breaking this rule is atomic::load/store
, which are independently named functions. One could have made them the same function, but being able to visually distinguish atomic load operations from stores is pretty important, since they can adversely affect the functionality of your code.
That being said, C++ as a whole has no guidelines on this. The above is just how the standard library handles it in most cases. Other libraries will frequently use get/set
. Some libraries will call out get
but not setting functions.
std::vector::begin()
vs.std::vector::cbegin()
. – amon Jul 3 '18 at 20:35std::as_const
, we can drop those – Caleth Jul 3 '18 at 20:39