I read that other operators do not needed anymore (except ==).
Right, except == is the key bit. There are two categories of comparison operators:
- equality operators (
==, !=)
- ordering 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.