João Pires
João Pires

Reputation: 1017

!= auto generated from == in C++20?

Is this standard behavior in C++20? I couldn't find anything about it in cppreference.

I've just tried both on Clang and on Visual Studio and it works and it doesn't give me any sort of error or warning. I also checked with the debugger to see if operator== was being called and it was! Does C++20 now allows for the automatic generation of operator!= when operator== is present? Does it default to a sane !(a == b)? If that's so, then that's awesome for C++!

Upvotes: 6

Views: 2036

Answers (2)

Antoine Morrier
Antoine Morrier

Reputation: 4076

What you can do in older C++ version is to use the CRTP (Curriously Recuring Template principle).

The idea is to have a template base, and the template parameter is the Derived class :

template <typename Derived>
class Comparable {
  public:
    friend constexpr auto operator!=(const Derived &a, const Derived &b) noexcept { return !(a == b); }

    friend constexpr auto operator<=(const Derived &a, const Derived &b) noexcept { return !(b < a); }

    friend constexpr auto operator>(const Derived &a, const Derived &b) noexcept { return b < a; }

    friend constexpr auto operator>=(const Derived &a, const Derived &b) noexcept { return !(a < b); }
};

And so, you can use it like this :

struct Example : Comparable<Example> {
    friend bool operator==(const Example &a, const Example &b);
    friend bool operator<(const Example &a, const Example &b);
};

If you declare only the == operator, you will have the != generated automatically, and if you provide both the < and == all operators will be defined :)

Upvotes: 2

eerorika
eerorika

Reputation: 238461

!= auto generated from == in C++20?

Is this standard behavior in C++20?

Yes. operator!= is auto generated from operator== in C++20.

Furthermore, all four relational operators are generated if you define operator<=>, and all of the comparison operators are generated if you define operator<=> as defaulted.

What you want to do in most cases:

struct example
{
    std::string a;
    int         b;

    auto operator<=>(const example&) const = default;
};

Upvotes: 8

Related Questions