I'm trying to understand the new default comparison operators introduced in C++20. My issue is about when an explicitly defaulted comparison operator gets implicitly defined. The following code example illustrates the question:
#include <iostream>
struct B
{
operator bool() const { return true; }
};
struct D : B
{
bool operator==(const D&) const = default;
};
bool operator==(B, B) { return false; }
int main ()
{ D d;
std::cout << (d == d);
}
/* Outputs:
0 in gcc 10.1
1 in msvc 19.26
*/
The output of this program is compiler-dependent. It seems that MSVC defines the operator== for class D when it is encounters the declaration as defaulted, hence it doesn't use the operator== that is defined later for class B. By contrast, gcc waits with the implicit definition of D's operator== until it is actually needed, by which time the operator== defined for B is in scope, and gets used. Which behavior, if either, is correct ?
A related question, is why a defaulted operator== can't be declared for a class with reference members ? I could see that reference members could pose a problem with the MSVC approach, because a reference member might refer to an incomplete type when the defaulting declaration for operator== is encountered. With the gcc approach, the reference's type would always be complete before gcc attempts to define the defaulted operator.