|
Boost : |
Subject: Re: [boost] [type_traits][function_types] Discard param const qualification, bug or feature?
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-09-26 07:50:46
On Thu, Sep 26, 2013 at 2:40 PM, Jonathan Wakely
<jwakely.boost_at_[hidden]>wrote:
> 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).
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk