Оператор сравнения по умолчанию с явным параметром объекта

В C++23 класс может иметь явные функции-члены объекта (с префиксом this перед первым параметром), включая операторы сравнения членов. Какие из них компилятор может сгенерировать автоматически после указания =default?

Я ожидал, что любой действительный оператор сравнения по умолчанию для друзей будет иметь аналогичный действительный оператор сравнения по умолчанию для явного члена объекта (после замены friend на this). Но на практике с нынешними компиляторами это не так.

Первый пример:

struct A { 
    // ok everywhere
    friend bool operator ==(A, A) = default;
    // #1, ok in GCC, error in Clang
    bool operator ==(this A, A) = default;
};

Здесь определение дружественного оператора принимается всеми компиляторами, но только GCC допускает #1, и Clang жалуется:

<source>:5:22: error: defaulted member equality comparison operator must be const-qualified
    5 |     bool operator ==(this A, A) = default;
      |                      ^
      |                           const
<source>:5:10: error: invalid parameter type for defaulted equality comparison operator; found 'A', expected 'const A &'
    5 |     bool operator ==(this A, A) = default;

Онлайн-демо: https://gcc.godbolt.org/z/qjTavxWv6

Во втором примере:

struct A { 
    // fails everywhere
    //friend bool operator ==(const A, const A &) = default;
    // #2, ok in Clang, error in GCC
    bool operator ==(this const A, const A &) = default;
};

Аналог недопустимого оператора друга принимается в Clang, а GCC отклоняет его:

<source>:5:10: error: defaulted 'bool A::operator==(this A, const A&)' must have parameters of either type 'const A&' or 'A', not both
    5 |     bool operator ==(this const A, const A &) = default;

Онлайн-демо: https://gcc.godbolt.org/z/4r3q9fTrh

Какие из явно заданных по умолчанию операторов (№1 или №2) действительно действительны?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Формулировка в [class.compare.default] довольно ясна:

Функция оператора сравнения по умолчанию ([over.binary]) должна быть нешаблонной функцией, которая

  • является нестатическим участником или другом какого-либо класса C,
  • определяется как значение по умолчанию в C или в контексте, где C завершено, и
  • либо имеет два параметра типа const C&, либо два параметра типа C, где неявный параметр объекта (если есть) считается первым параметром.

Итак, это действительно:

struct A { 
    bool operator ==(this A, A) = default;
};

и это не:

struct A { 
    bool operator ==(this const A, const A &) = default;
};

Другие вопросы по теме