C++ Logo

std-discussion

Advanced search

Re: Conditional operator with const lvalue and non-const prvalue

From: Krystian Stasiowski <sdkrystian_at_[hidden]>
Date: Mon, 23 Sep 2019 19:04:43 -0400
Actually, no... top level qualifiers are ignore... I'm not sure then.

On Mon, Sep 23, 2019 at 6:51 PM Krystian Stasiowski <sdkrystian_at_[hidden]>
wrote:

> Only the last case where the initializer expression is converted does it
> not bind directly http://eel.is/c++draft/dcl.init.ref#5.4
>
> The implicit conversion sequence can be formed from the prvalue to the
> lvalue. Since constness matters for prvalues of class type and is not
> ignored, an implicit conversion sequence cannot be formed from const S to
> S.
>
> I think.
>
> On Mon, Sep 23, 2019 at 11:02 AM Brian Bi via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>
>> Consider the following:
>>
>> #include <type_traits>
>> struct S {};
>> bool b;
>> int main() {
>> const S s {};
>> static_assert(std::is_same<decltype(b ? S{} : s), const S>::value);
>> }
>>
>> Here <http://coliru.stacked-crooked.com/a/49d1853146cbcdc1> GCC and
>> Clang confirm that the type is correct. But I can't figure out why. My
>> reading of the standard is that the result should be a prvalue of type S,
>> not const S.
>>
>> [expr.cond]/4 applies because the two operand types are not the same (one
>> is S, the other is const S) but at least one is a class type. We must
>> therefore try to form an implicit conversion sequence in each direction. An
>> implicit conversion sequence cannot be formed from the prvalue operand to
>> const S& because (4.1) contains a restriction that the reference must bind
>> directly to a glvalue. In the other direction, we have the identity
>> conversion sequence from the const lvalue operand to S. Thus, /4 seems to
>> tell us that the const lvalue operand must be converted to S, and the
>> result should have type S.
>>
>> Yet I would not expect both GCC and Clang to be wrong here, so I think
>> that I have misunderstood the standard in this case. Surely there must be a
>> reason why the result has type const S, but I can't figure it out.
>>
>> (Even if we assume that the compiler is obligated to perform an
>> lvalue-to-rvalue conversion on the const lvalue operand, resulting in a
>> const prvalue, that still doesn't seem to explain the result. If this were
>> the case, /4 would end with a const prvalue and a non-const prvalue, /5
>> would not apply, and we would get to /6 and the types would still not be
>> the same. The "overload resolution" procedure prescribed there would fail
>> since S can't be converted to any scalar types, making the program
>> ill-formed. This interpretation thus cannot be correct either.)
>>
>> --
>> *Brian Bi*
>> --
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>

Received on 2019-09-23 18:07:05