Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++20 explicitly defaulted equality operator

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.

like image 922
user1958486 Avatar asked Jul 17 '20 13:07

user1958486


People also ask

Is there a default == operator in C++?

If operator<=> is defaulted and operator== is not declared at all, then operator== is implicitly defaulted.

How do you write an equality operator in C++?

The equality operators in C++ are is equal to(==) and is not equal to(!=). They do the task as they are named. The binary equality operators compare their operands for strict equality or inequality. The equality operators, equal to (==) and not equal to (!

Which of the following is an equality operator?

The equality operator (==) is used to compare two values or expressions. It is used to compare numbers, strings, Boolean values, variables, objects, arrays, or functions.

How does C check equality?

Checking for equality in C and C++ identifier == identifier; The == sign is used to compare primitive types such as char, int, float, etc. The comparison operator returns true if the two identifiers are equal.

Which operators have higher precedence than equality operators?

The first four operators in the list above have a higher precedence than the equality operators ( == and != ). See the precedence information in the table Precedence and Associativity of C Operators. The operands can have integral, floating, or pointer type. The types of the operands can be different.

What are the relational and equality operators in C?

The relational and equality operators test the following relationships: The first four operators in the list above have a higher precedence than the equality operators ( == and != ). See the precedence information in the table Precedence and Associativity of C Operators. The operands can have integral, floating, or pointer type.

What is the equality comparison function in C++?

The equality comparison function (whether defaulted or not) is called whenever values are compared using == or != and overload resolution selects this overload. Like defaulted special member functions, a defaulted comparison function is defined if odr-used or needed for constant evaluation .

What is the inequality operator in C++?

Inequality operator != The inequality operator != returns true if its operands are not equal, false otherwise. For the operands of the built-in types, the expression x != y produces the same result as the expression ! (x == y). For more information about type equality, see the Equality operator section.


1 Answers

GCC is wrong here (not unsurprisingly considering its results). When creating the definition of a defaulted comparison operator, the standard says:

Name lookups in the defaulted definition of a comparison operator function are performed from a context equivalent to its function-body.

And the function body of a defaulted function is where = default is. Therefore, the bool operator==(B, B) function should not be visible to the function body of the defaulted comparison operator.

like image 155
Nicol Bolas Avatar answered Oct 27 '22 22:10

Nicol Bolas