Boost logo

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