Like many other people, from an API point of view, all are equivalent and equal for overload resolution:
void foo( int ); void foo( const int );
But the best question is whether this gives any semantic meaning to the consumer of this API or whether it provides any coercion to good behavior from the implementation developer.
Without any well-defined developer coding rules that directly define this, const scalar arguments have no obvious semantic meaning.
From the consumer: const int does not change your input. It can still be literal, or it can be from another variable (both const and non- const )
From the developer: const int imposes a restriction on the local copy of the variable (in this case, the function argument). It just means changing the argument, you take another copy of the variable and change it.
When a function that takes an argument is called, a copy of this argument is created on the stack for the called function. This gives the function a local copy of the argument for its entire area, which can then be changed, used for calculations, etc. - without affecting the original input transferred to the call. In fact, this provides a local variable argument for its input.
Marking the argument as const , it simply means that this copy cannot be modified; but he does not prohibit the developer from copying it and making changes to this copy. Since it was a copy from the very beginning, it does not provide all of this from within the implementation - and ultimately does not matter much from the consumer's point of view.
This contradicts passing by reference, where the reference to int& semantically different from const int& . The first is able to mutate its contribution; the latter can only observe the input (provided that the implementation is not const_cast const -ness), but allows you to ignore this possibility); thus, const -ness on links has an implied semantic meaning.
This does not greatly benefit the public API; and (imo) introduces unnecessary restrictions on the implementation. As an arbitrary, far-fetched example, a simple function like:
void do_n_times( int n ) { while( n-- > 0 ) {
Now you will need to write using an unnecessary copy:
void do_n_times( const int n ) { auto n_copy = n; while( n_copy-- > 0 ) {
Regardless of whether const scalars are used in the public API, one key thing must be consistent with the design. If the API randomly switches between using scanning const arguments using unscanned const scalars, this can cause confusion as to whether this is implied for any implied value to the consumer.
TL; DR: const scalar types in the public API do not convey semantic meaning unless explicitly defined by your own recommendations for your domain.