Date: Sun, 01 Dec 2024 19:06:52 +0300
On December 1, 2024 8:34:55 AM Arthur O'Dwyer via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> One of the drastic changes in P3039 was the idea that maybe instead of
> making
> auto operator->() const = default;
> define a new member function definition, we should simply add a rewrite
> rule just like the existing (C++20) rewrite rule for (a < b). We could say
> that (a -> b) will perform lookup for both (a.operator->) *and*
> (a.operator*) in exactly the same way that (a < b) performs lookup for both
> (a.operator<) *and* (a.operator<=>). (And add similar rules for deciding
> which candidate is the best match.)
>
> This would also influence your proposal about (a++): Should you actually
> make
> auto operator++(int) = default;
> define a new member function definition, or should you simply add a rewrite
> rule that makes (a++) perform lookup for both variants of operator++ and
> fall back to the prefix version (plus the copy constructor) if the postfix
> version isn't available? Your motivation touches on that question here:
>
> Would it not be nice to be able to just write
>> T operator++(int) = default;
>> and never have to bother with it again, just like you can write
>> bool operator!=(const T&, const T&) = default;
>> and get the expected result.
>
>
> You *can* write `operator!=(...) = default`, but no C++20 programmer ever
> *would* write it, because we have a rewrite rule that handles that
> transparently, without the programmer's intervention. So, it seems like it
> would make sense to handle postfix `++` in the same way, right?
FWIW, C++20 operator rewriting rules did break real world code,
specifically Boost.Operator, which remains broken under C++20 and later to
this day. This is one of the reasons why some code bases decided to remain
on C++17 and not upgrade. IMO, accepting those rules into the standard was
premature at best, entirely bad idea at worst.
This should be a cautionary tale for anyone suggesting more rewriting rules
in the standard.
<std-proposals_at_[hidden]> wrote:
> One of the drastic changes in P3039 was the idea that maybe instead of
> making
> auto operator->() const = default;
> define a new member function definition, we should simply add a rewrite
> rule just like the existing (C++20) rewrite rule for (a < b). We could say
> that (a -> b) will perform lookup for both (a.operator->) *and*
> (a.operator*) in exactly the same way that (a < b) performs lookup for both
> (a.operator<) *and* (a.operator<=>). (And add similar rules for deciding
> which candidate is the best match.)
>
> This would also influence your proposal about (a++): Should you actually
> make
> auto operator++(int) = default;
> define a new member function definition, or should you simply add a rewrite
> rule that makes (a++) perform lookup for both variants of operator++ and
> fall back to the prefix version (plus the copy constructor) if the postfix
> version isn't available? Your motivation touches on that question here:
>
> Would it not be nice to be able to just write
>> T operator++(int) = default;
>> and never have to bother with it again, just like you can write
>> bool operator!=(const T&, const T&) = default;
>> and get the expected result.
>
>
> You *can* write `operator!=(...) = default`, but no C++20 programmer ever
> *would* write it, because we have a rewrite rule that handles that
> transparently, without the programmer's intervention. So, it seems like it
> would make sense to handle postfix `++` in the same way, right?
FWIW, C++20 operator rewriting rules did break real world code,
specifically Boost.Operator, which remains broken under C++20 and later to
this day. This is one of the reasons why some code bases decided to remain
on C++17 and not upgrade. IMO, accepting those rules into the standard was
premature at best, entirely bad idea at worst.
This should be a cautionary tale for anyone suggesting more rewriting rules
in the standard.
Received on 2024-12-01 16:06:55