C++ Logo

std-proposals

Advanced search

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

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Wed, 24 Jan 2024 15:13:02 +0000
Hi Matthew,

A counter example that comes to mind is when the user intentionally wants to disallow copy, it may still be valid to a do logical increment of the object "in-place", but you wouldn't want to provide a copy of the object.
I supposed you could check if the object was copy constructable first before enabling the rule? But I'm not sure if automatically defining operators that a user hasn't asked for is a good idea,
I would rather have facilities that would help write the boiler plate code instead, how that would look like will require some investigation.

And I agree, having to pass an unused int to distinguish between the pre and post versions of the operator is ugly (although not much of an issue when the code gets compiled), there might be a better way to define that without creating phantom variables.

br,
Tiago

From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of Matthew Taylor via Std-Proposals
Sent: Wednesday, 24 January 2024 15:44
To: std-proposals_at_[hidden]
Cc: Matthew Taylor <mjtaylor214_at_[hidden]>
Subject: [std-proposals] Should postfix increment and decrement operators be automatically obtainable from their prefix versions?

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.

Received on 2024-01-24 15:13:05