Rule A13-5-4 (required, implementation, automated)

If two opposite operators are defined, one shall be defined in terms of the other.

Rationale

Defining one operator in terms of the other simplifies maintenance and prevents from accidental errors during code development. Note: Completeness of relational operators can be achieved by implementing just operator== and operator< and using namespace rel_ops.

Example

// $Id: A13-5-4.cpp 328319 2018-08-03 14:08:42Z christof.meerwald $
#include <cstdint>

// non-compliant
class A
{
public:
explicit A(std::uint32_t d) : d(d) {}

friend bool operator==(A const & lhs, A const & rhs) noexcept
{
return lhs.d == rhs.d;
}
friend bool operator!=(A const & lhs, A const & rhs) noexcept
{
return lhs.d != rhs.d;
}

private:
std::uint32_t d;
};

// compliant
class B
{
public:
explicit B(std::uint32_t d) : d(d) {}

friend bool operator==(B const & lhs, B const & rhs) noexcept
{
return lhs.d == rhs.d;
}

friend bool operator!=(B const & lhs, B const & rhs) noexcept
{
return !(lhs == rhs);

}
private:
std::uint32_t d;
};

See also

JSF December 2005 [8]: AV Rule 85: When two operators are opposites (such as == and !=), both will be defined and one will be defined in terms of the other.