This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116c. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-03-14


3007. Access checking during synthesis of defaulted comparison operator, take 2

Section: 11.10.1  [class.compare.default]     Status: open     Submitter: Jason Merrill     Date: 2025-03-13     Liaison: EWG

Issue 2568 sought to make the following situation well-formed:

   struct Base {
   protected:
     bool operator==(const Base& other) const = default;
   };

   struct Child : Base {
     int i;
     bool operator==(const Child& other) const = default;
   };

   bool b = Child() == Child(); // error: deleted operator==

However, the applied resolution of that issue failed to achieve the intent, because the object expression has type Base when invoking Base::operator== in the synthesized body of Child::operator==, per 11.10.1 [class.compare.default] paragraph 5 together with 11.10.2 [class.eq] paragraph 2 and 11.10.3 [class.spaceship] paragraph 2. The synthesized body of Child::operator== looks like this:

   bool Child::operator==(const Child& other) const
   {
     return (static_cast<const Base&>(*this) == static_cast<const Base&>(other)); // error, protected
   }

Additional notes (March, 2025)

EWG should decide whether the design intent is to allow access to Base::operator== in the example. Forwarded to EWG with paper issue #2239 by decision of the CWG chair.