On Thu, Sep 26, 2013 at 2:40 PM, Jonathan Wakely
On 26 September 2013 11:02, Andrey Semashev wrote:
Sure, they work the same, from the caller's perspective. But is that a reason to cheat with the type system?
void foo(int); void bar(const int);
typeid(&foo) == typeid(&bar); // why?
My point was that despite the same behavior on the caller's side, the functions have different signatures,
No they don't. "Signature" has a specific meaning in C++ and they have the same signature.
Ok, I used the term "signature" for the lack of a better word.
They have different tokens in the declaration, but so do these:
signed long int i; long j;
That doesn't mean they have different types.
Yes, but that's not the case with long and const long, is it?
and I don't see why there was a _necessity_ to force the compiler to drop cv-qualifiers from the function argument types. In other words, it makes the language more complicated for no apparent reason.
There are reasons.
If they were different signatures would you be able to overload based on top-level const-ness of parameters?
The functions with different qualification of arguments would be considered distinct, yes. Whether or not such declarations would result in compile time error is another question.
Would that be useful?
No, the overload would be always ambiguous. Because of this it would probably be a good idea to always generate an error when such overloads are found.
If the function takes its arguments by-value why do you (the caller) care what it does with that parameter?
No, and as I said, the top level cv-qualification of function arguments would still be transparent for the caller. Unless he wants to know the exact "signature" (I'm using the term loosely here again) of the function.
It should be able to modify it or not, without that affecting the function signature the caller sees. Whether the parameter is const or not is an internal detail to the function, not part of the interface.
True. I'm not really arguing with that. It's just that the outcome of this reasoning appears unexpected for newcomers.
Currently template argument deduction is constistent, and doesn't deduce a top-level const. If functions didn't ignore top-level const on parameters would argument deduction have to change to deduce top-level const-ness? e.g.
template<typename T> void f(T by_value) { ++by_value; }
int i; const int ci;
f(i); f(ci);
Should that call two different template specializations? Doing so would break the function template in the f(ci) case because T would be 'const int' and non-modifiable.
No, both calls would invoke f<int>(int) with signature void(int). However, if f was declared like this: template< typename T > void f(const T by_value); then both calls would invoke f<int>(const int) with signature void(const int).