C++ Logo

std-proposals

Advanced search

Re: Bringing consistency to implicit conversion by ref-qualified conversion functions

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Wed, 30 Dec 2020 16:50:44 -0500
On Wed, Dec 30, 2020 at 4:27 PM Hani Deek via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> One area in C++ where there is significant complexity and inconsistency is
> the way compilers handle ref-qualified implicit conversion functions.
>
> I believe that most C++ users who put ref-qualifiers on implicit
> conversion functions expect those ref-qualifiers to have the same effect in
> all situations. Probably few know that the ref-qualifiers will have
> different effects in different situations, as illustrated by the examples
> below.
>

https://godbolt.org/z/8a9Tcc
struct S {
    operator float() &&;
    operator int() const&;

    operator int*() &&;
    operator float*() const&;

    operator A() &&;
    operator B() const&;
};

void prim(float);
void prim(int);
void ptr(int*);
void ptr(float*);
void obj(A);
void obj(B);

void test() {
    prim(S()); // OK
    ptr(S()); // error, ambiguous
    obj(S()); // error, ambiguous
}

Agreed, this doesn't seem to make any sense. But is this perhaps just an
implementation bug (in *all* these compilers)? What possible reason could
there be for the `int/float` case being unambiguous but the `int*/float*`
case being ambiguous? Both cases involve primitive types. Do *you*
understand why the implementations are doing what they're doing here?
because *I* definitely don't.

If you're proposing a specific wording change to the Standard — as opposed
to just detecting a weird bug in every implementation, which I haven't
completely ruled out — then it'll help your case to say *why* you want to
have a class type with multiple ref-qualified conversion operators to
different types. Is this a real-world situation you're running into, or
just a bit of trivia?

Also, for the record, ref-qualified conversion operators are superficially
relevant to P1155 "More implicit moves" (adopted in C++20) / P2266 "Simpler
implicit move" (forthcoming, targeting C++2b), but Hani's issue is
orthogonal and unrelated to P1155/P2266. P1155/P2266 deal with "implicit
move" scenarios like
https://godbolt.org/z/MnhKEK
whereas Hani's scenarios involve situations where the thing being
converted is legitimately a prvalue already, no "implicit move" needed.

my $.02,
–Arthur

Received on 2020-12-30 15:51:00