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 18:51:06 -0400
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 17:53:28