In g++ 10, I am trying to use three way comparison, just for experiment.
I read that other operators do not needed anymore (except ==).
But even if I can use operator (it is implemented on the compiler), it does not supersede (or imply) !=.
So, the following code does not work.
#include<iostream>
using namespace std;
struct A
{
    struct Iterator
    {
        size_t index;
        size_t operator*() { return index + 1000; }
        //bool operator!=(const Iterator &a) const { return index != a.index; }
        auto operator<=>(const Iterator &a) const { return index <=> a.index; }
        Iterator &operator++() { ++index; return *this; }
    };
    Iterator begin() { return Iterator{0}; }
    Iterator end() { return Iterator{5}; }
};
int main()
{
    A a;
    auto result = a.begin() <=> a.end();
    for (auto b : a)
        cout << b << "\n";
    cout << (a.begin() != a.end()) << "\n";
    return 0;
}
What am I missing here?
I read that other operators do not needed anymore (except ==).
Right, except == is the key bit. There are two categories of comparison operators:
==, !=)<=>, <, >, <=, >=)In each of those categories, the first one I listed (== and <=>) is the primary comparison operator. It is the only operator that you need to define if you want to opt in to that category. If you want equality, provide ==. If you want ordering, provide <=> (and also ==). The other comparison operators are secondary comparison operators - expressions using secondary comparison are, in C++20, rewritten to use the primary comparison operator. 
These categories are completely distinct† - there is no crossover. A x != y expression can invoke operator==(x, y) or even operator==(y, x) but it will never invoke an operator<=> of any kind. 
You have code that requires an equality comparison but don't have the equality operator defined, hence it's ill-formed. To get this to work, you need to add:
bool operator==(const Iterator &a) const { return index == a.index; }
auto operator<=>(const Iterator &a) const { return index <=> a.index; }
Note ==, not !=. You should not declare secondary comparison operators in C++20, unless you have a very specific need for them (and this is not such a need).
For more, see Comparisons in C++20.
†The single exception to this rule is, for convenience, if you default operator<=> then you also get a declared, defaulted operator==. It's as if you had defaulted both yourself. In this example, since your comparisons are just the default member-wise comparisons, you could have written:
auto operator<=>(const Iterator &a) const = default;
As your single comparison operator declaration, which would've behaved as if you'd written:
bool operator==(const Iterator &a) const = default;
auto operator<=>(const Iterator &a) const = default;
Which gives you the correct equality operator you need for your program.
From cppreference:
In brief, a class that defines
operator<=>automatically gets compiler-generated operators <, <=, >, and >=. A class can defineoperator<=>as defaulted, in which case the compiler will also generate the code for that operator."
The code for != and == is not generated, thus you do need to implement the comparisons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With