[Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

Thiago Macieira thiago.macieira at intel.com
Wed Jul 26 17:18:59 CEST 2023


On Wednesday, 26 July 2023 02:58:51 PDT Ivan Solovev via Development wrote:
> > That means it can't be used in ADL contexts without scope qualifications,
> > but I don't see that as an API requirement. The API should be the
> > operators.
> We introduce new public macros, which means that users will be using them in
> their custom classes in order to achieve the same unified comparison
> behavior between C++17 and C++20.
> This means that the users will have to implement the helper functions
> required for these macros. I agree that for the equal()/equals() helper
> function, the op==() and op!=() are mostly usable.
> But what about the order()/compare() function? I assume that the users would
> NOT be able to use op<=>(), because they will write C++17-compatible code.
> And testing for Unordered in terms of C++17 relational operators looks like
> an unnecessarily large amount of code, especially if we already have
> written this code for them. So why not just let them use it?
> Of course, you can argue that they can use the public APIs directly (if they
> exist). But what if the user develops a generic class?

What I meant is that the product API of using the macros are the set of 
operators. The methods that those operators called are not API and users are 
not expected to use them in their code. In fact, if conflicting names are a 
problem, then we should uglify the names we're asking for in the macros by 
inserting a "q_" or "qt_" prefix.

This means C++17 users are able to use all operators to produce a boolean 
result, but can't get a QXxxOrdering result with homogeneous API from the 
macros.

We still need *some* level of public API to produce ordering results because 
users will need those methods to produce their own comparison functions, such 
as composing on top of our string or date/time classes. If they want to also 
be compatible with C++17, then they can't use the spaceship, and instead they 
will need to call a named function of some sorts. If we are going to expose 
API, then said API must have proper names and thus must be "equals" and 
"compare".

But again, these do not need to be the functions that the macros call 
directly. The macros may call adaptor functions with ugly names.

> What we can do is to have both private/public static two-arg member and a
> hidden friend, which would simply call the static method. We will have to
> apply this hack only to the classes that already have public APIs with the
> clashing names. For other classes we can just use hidden friends directly.

I don't see the need for anything to be a hidden friend. We need a *name* that 
compiles, that's all.

> > You forgot the <=> 0 here. Comparing an int with 0 through the spaceship
> > operator produces a std::strong_ordering result. And comparing a
> > std::strong_ordering with 0 via the spaceship returns itself too.
> > 
> > https://gcc.godbolt.org/z/ebKe8Eb3a
> > 
> > This works for weak_ordering too. For partial_ordering, the case of
> > unordered needs to be handled explicitly, so I'd instead require that the
> > called function return either std::partial_ordering or QPartialOrdering,
> > nothing else.
> 
> Well, the idea was to avoid unnecessary operations, and basically optimize
> operator<=>() to simply call the helper function in C++20 case.

Agreed, but your argument does not refute my proposal. What I suggested is 
still optimal for strong and weak ordering.

The only problem is partial ordering because QPartialOrdering::Unordered's 
value does not match two of the three Standard Libraries' values (for Qt 7, we 
can fix this now that we know what those values are). And even then, this only 
applies if someone is actually storing that number or passing it through an 
opaque ABI boundary. If instead everything is inline, the compiler's optimiser 
should simply emit optimal code.

> But anyway, that's a nice approach, and I should consider using it in my
> patches. Specially if it allows us to "unblock" compare() as a name for the
> helper function.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Cloud Software Architect - Intel DCAI Cloud Engineering
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5152 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20230726/771df7f2/attachment.bin>


More information about the Development mailing list