In C++20, secondary comparaison operators are possibly rewritten from their primary operators. This, generally, is not a concern as far as the operator== retturns a boolean. This is not the case as the UBool is an integer. As a matter of fact, the compiler is not able to rewrite the operator!=. We have to help it a little: I will give a PR soon.
Actually, there are some changes I did not put in the PR because as you say it seems that there are still some bugs in gcc 10 support of C++20. I keep them on my side while I am waiting an answer to this ticket I opened while investigating the compilation issues with ICU: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93699.
So maybe some changes, especially in the base class are not needed. I will try to improve my PR to have a minimal changes set when I have the confirmation it is (or not) a bug.
Not finding that the subclass inherits operator!= from the base class has got to be a compiler bug.
The rules have changed for comparison operators with C++20. E.g.: the compiler will synthesize operator!= if you have operator== and it will also synthesize candidates with the arguments reversed.
It does not look like GCC will accept the bug. My first suggestion would be to change the return type of all comparison operators to bool.
But changing return type to bool is not enough to fix all comparison operator issues. Using TimeUnitFormat as an example. Extracted and simplified the problematic operators.
Clang 10 and GCC 10 rejects the code in C++20 mode
Both compilers accept the code after deleting TimeUnitFormat::operator!=
It is kind of redundant but saves a virtual call in preC++20 mode. Clang still gives a warning about ambiguity.
In this case I would delete TimeUnitFormat::operator!= and instead provide MeasureFormat::operator==(const MeasureFormat&) and MeasureFormat::operator!=(const MeasureFormat&). Still saving a virtual call in pre-C++20 and no ambiguity warning + potential error in current and future compilers in C++20 mode
TimeUnitFormat is deprecated but other Format types have similar issues.
Fredrik reviewed the standard changes, and we discussed this today in the team meeting. In fact the C++ standard has deliberately changed and breaks existing code, and the cleaner solution will require long-lived conditional code à la #if C++20 or later.
We could add lots of additional operators returning UBool, but we decided it’s cleaner and simpler to change operator== to return bool and conditionally (if C++20 or higher, rather than earlier versions) remove operator!=. Other API will continue to use UBool.
Fredrik, please add more details about the problem and the two options, as discussed.