Boost logo

Boost :

Subject: Re: [boost] [type traits extension] test for const volatile& as return type
From: Frédéric Bron (frederic.bron_at_[hidden])
Date: 2011-07-16 18:50:53


> I take that back -- the Intel compiler is right, GCC and MSVC are wrong.
>
>    void g(int const volatile&);
>    void g(...);
>
> When calling g with an int rvalue, the compiler must select the
> `void g(int const volatile&)` overload because "a standard conversion sequence
> is a better conversion sequence than a user-defined conversion sequence or an
> ellipsis conversion sequence". Only then does the compiler decide that calling
> `void g(int const volatile&)` with an int rvalue is illegal. And this is not
> without precendence -- quoting §13.3.3.1.4/4:
>
>> Other restrictions on binding a reference to a particular argument do not
>> affect the formation of a standard conversion sequence, however. [Example: a
>> function with a "reference to int" parameter can be a viablecandidate even if
>> the corresponding argument is an int bit-field. The formation of implicit
>> conversion sequences treats the int bit-field as an int lvalue and finds an
>> exact match with the parameter. If the function is selected by overload
>> resolution, the call will nonetheless be ill-formed because of the prohibition
>> on binding a non-const reference to a bit-field.]
>
> Summary: Intel *is correct* according to the standarde, but GCC and MSVC take
> the sane/practical route.

I am not sure of your interpretation.

Here are other parts of the standard:
§ 13.3.2 Viable functions:
"for F to be a viable function, there shall exist for each argument an
implicit conversion sequence
(13.3.3.1) that converts that argument to the corresponding parameter
of F. If the parameter has reference
type, the implicit conversion sequence includes the operation of
binding the reference, and the fact that a
reference to non-const cannot be bound to an rvalue can affect the
viability of the function (see
13.3.3.1.4)."

§ 13.3.3.1.4/3:
"A standard conversion sequence cannot be formed if it requires
binding a reference to non-const to an
rvalue (except when binding an implicit object parameter; see the
special rules for that case in 13.3.1).
[Note: this means, for example, that a candidate function cannot be a
viable function if it has a non-const
reference parameter (other than the implicit object parameter) and the
corresponding argument is a temporary
or would require one to be created to initialize the reference (see 8.5.3). ]"

So the question is: is "const volatile &" a "reference to non-const"?
Or does "reference to non-const" mean exaclty T const & (excluding
additionnal volatile qualifier) or not?
If T const volatile & is considered as "reference to non-const" then
Intel is wrong.
If not, Intel is right.

§8.5.3/5 you quoted earlier suggests that "reference to non-const" is
only T const & which would mean that Intel is wrong:
"A reference to type “cv1 T1” is initialized by an expression of type
“cv2 T2” as follows:
— If the initializer expression
— is an lvalue (but is not a bit-field), and “cv1 T1” is
reference-compatible with “cv2 T2,” or
— has a class type (i.e., T2 is a class type) and ...
— Otherwise, the reference shall be to a non-volatile const type
(i.e., cv1 shall be const)."

Frédéric


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