Rule A13-5-5 (required, implementation, automated)
Comparison operators shall be non-member functions with identical parameter types and noexcept.
Rationale
Any asymmetric behavior for comparison functions can be confusing. In order to achieve fully symmetric treatment, comparison functions need to be defined as nonmember functions, as the implicit object parameter of a member function does not allow user-defined conversions to be applied (but the right hand side would). Since comparison is a fundamental operation, it should never throw an exception. Note: This rule applies to ==, !=, <, <=, >, and >= Note: Declaring a comparison operator as a friend allows it to access internal data similar to a member function and is allowed by exception in rule A11-3-1.
Example
// $Id: A13-5-5.cpp 325916 2018-07-13 12:26:22Z christof.meerwald $
#include <cstdint>
class A
{
public:
explicit A(std::uint32_t d)
: m_d(d)
{}
bool operator ==(A const & rhs) const // Non-compliant: member, not noexcept
{
return m_d == rhs.m_d;
}
private:
std::uint32_t m_d;
};
class C
{
public:
operator A() const;
};
void Foo(A const & a, C const & c)
{
a == c; // asymmetric as "a ==c" compiles, but "c == a" doesn’t compile
}
class B
{
public:
explicit B(std::uint32_t d)
: m_d(d)
{}
Compliant: non-member, identical parameter types, noexcept friend bool operator
==(B const & lhs, B const & rhs) noexcept
{
return lhs.m_d == rhs.m_d;
}
private:
std::uint32_t m_d;
};
class D
{
public:
operator B() const;
};
void Bar(B const & b, D const & d)
{
b == d;
d == b;
}
See also
C++ Core Guidelines [11]: C.86: Make == symmetric with respect to operand types and noexcept