C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Should postfix increment and decrement operators be automatically obtainable from their prefix versions?

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Wed, 24 Jan 2024 16:10:13 +0000
On Wed, 24 Jan 2024 at 14:46, Matthew Taylor via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> In the overwhelming majority of cases a class which is considered
> incrementable should provide both prefix and postfix operators in order to
> do as the ints do; and in that case there is a universal semantic
> definition and even implementation for the postfix operator which is
> written in terms of the prefix one.
>
> As such, I posit that it would be beneficial if there were a mechanism to
> automatically obtain one set of operators from the other, in a similar vein
> to the changes to the equality operators in C++20. For these operators, the
> change would be much simpler than the equality operator due to the lack of
> a need to allow reversed parameter lists; as well as simpler than some
> operators which have previously been proposed to be automatically obtained
> because of just how singular the meaning of operator++ is.
>
> The motivation here is threefold. For one, it reduces a lot of boilerplate
> as per the status quo the programmer effectively needs to write two
> different operator overloads for the same conceptual operation.
> Additionally, the convention of an unused int parameter to distinguish
> postfix from prefix is a bit of a rough edge, and exploring ways to smooth
> out rough edges and special case rules is in my opinion always worth doing.
> Thirdly, automatically generated operators help to enforce proper
> semantics, minimising the chances of a user (accidentally or otherwise)
> creating postfix operators which behave in unexpected ways. This change
> allows programmers to not worry about that and simply get on with what
> overloading operator++ should be - defining what incrementing their class
> means.
>
> Syntactically, I would suggest that if there exists a user-defined
> operator++() or operator--() for a class, and there is no user-defined
> corresponding postfix overload, that the compiler can generate those
> postfix overloads, following the conventional pattern of calling the prefix
> overload and returning a copy of the object with its original value. If the
> user does declare a postfix operator then the compiler will not generate
> one, and if the class is not copyable (and there is no user-provided
> operator) then the postfix operator is defined as deleted.
>
> I'd be interested to hear opinions, particularly if anyone has good
> counter examples for when a user would specifically want prefix operators
> but not postfix ones for a good semantic reason.
>

Somewhat related,
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2727r3.html would
reduce a lot of the boilerplate.

I'd still be in favour of synthesizing post-inc/post-dec from the
pre-inc/pre-dec operators even with that feature in the library. If the
synthesized forms wouldn't be correct or wouldn't be desirable you could
still define them manually, or define them as deleted.

We could always say that they're not synthesized by default, unless you do:

auto operator++(int) = default;
auto operator--(int) = default;

This couldn't change the meaning of any existing code, since you need to
add the new definitions to opt-in to the new rule.

Having this would remove a LOT of repetitive boilerplate from the standard
library specification as well. I can't find it now, but I thought I'd
opened an issue against the draft suggesting blanket wording to say that
unless otherwise specified, all post-inc and post-dec operators do the
obvious thing, so we don't need to keep describing their effects in detail.

Received on 2024-01-24 16:11:31