Boost logo

Boost :

Subject: Re: [boost] [type_traits][function_types] Discard param const qualification, bug or feature?
From: Rob Stewart (robertstewart_at_[hidden])
Date: 2013-09-26 05:28:31


On Sep 25, 2013, at 5:09 AM, Andrey Semashev <andrey.semashev_at_[hidden]> wrote:

> On Wed, Sep 25, 2013 at 12:48 PM, Rob Stewart <robertstewart_at_[hidden]>wrote:
>
>> On Sep 25, 2013, at 2:57 AM, Krzysztof Czainski <1czajnik_at_[hidden]>
>> wrote:
>>
>>> 2013/9/25 Mostafa <mostafa_working_away_at_[hidden]>
>>>
>>>> Both the type_traits and function_types library discard parameter const-qualifiers when decomposing function types. Is this a bug or a
>>>> feature? If a feature, then it's surprising enough behaviour that I think it warrants some documentation in both libraries.
>>
>> [snip]
>>
>>>> typedef void (foo)(int const);
>>>
>>> The two function declarations:
>>> void f(int);
>>> void f(int const);
>>> declare the same function, not an overload.
>>
>> Right. Top level const is not part of the function's type.
>>
>>> Const added to an argument type passed by value doesn't change the function signature. It is because the parameter will be copied anyway, and the const refers to how the argument will be treated inside the function's implementation.
>>
>> Exactly.
>
> I have to say that while these rules are logical and understandable when
> explained, types of function arguments are a constant source of confusion.

There are many things about C++ that are contrary to someone's intuition. That parameter declaration is no different than the following variable:

int const i;

When used with either of the forms of f(), above, does i work any differently than j, below?

int j;

They work alike with either f(), because the int is copied. The difference is whether you can change the int after initialization. The parameters are no different.

> The described above quirk with const arguments can be considered quite rare
> as people usually don't declare arguments that way.

Maybe you're right, but I always do so, by default.

> But C++11 brought us
> rvalue references, and the following:
>
> foo(int&& n)
> {
> // n is _not_ rvalue reference here
> }
>
> I understand the rationale for this, and it seems the right thing. But once in a while, when yet another fellow developer asks me why is that so, I wonder if it would be better if the standard was more straight-forward in
> this part.

The issue comes down to one of consequences. If n were still an rvalue, within foo(), even when referenced by name, what problems will that cause?

___
Rob

(Sent from my portable computation engine)


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk