Явное сравнение constexpr по умолчанию

После регрессии в GCC 13.3 мне пришлось добавить constexpr к операторам космического корабля по умолчанию в моей программе, и я заметил некоторые несоответствия в том, как компиляторы обрабатывают некоторый код в режиме C++20. Для краткости кода их можно отобразить в операторе сравнения на равенство ниже.

Пример №1:

struct A {
    operator int() const;
};

struct B : A {
    constexpr bool operator==(const B &) const = default;
};

это нормально для Clang и MSVC, но GCC с опцией -pedantic-errorsжалуется здесь:

ошибка: вызов функции, отличной от constexpr, 'A::operator int() const' [-Winvalid-constexpr]

Пример №2:

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

struct B : A {
    constexpr bool operator==(const B &) const = default;
};

что подходит только для MSVC, в то время как Clang с опцией -pedantic-errors начинает отклонять также с помощью

ошибка: определение оператора сравнения на равенство по умолчанию, который объявлен constexpr, но вызывает функцию сравнения, отличную от constexpr, является расширением C++23 [-Werror,-Wc++23-default-comp-relaxed-constexpr]

Оба примера кода действительны только для C++23 и недопустимы для C++20?

Не уверен, что первый фрагмент должен вызывать operator int, но вызов функций, не являющихся constexpr, в constexpr действительно разрешен только начиная с C++23.

Jarod42 10.08.2024 18:32
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это P2448R2, ослабляющее некоторые ограничения constexpr. В частности, для примера OPs снимается следующее ограничение:

(удалено) [dcl.constexpr]/6 Для функции constexpr или конструктора constexpr, который не является ни значением по умолчанию, ни шаблоном, если не существует значений аргументов, таких, что вызов функции или конструктора мог бы быть вычисленным подвыражением основного константного выражения, или, для конструктора, вычисленное подвыражение полного выражения инициализации некоторого объекта, инициализируемого константой ([basic.start.static]), программа имеет неверный формат, диагностика не требуется.

А также устраняется концепция совместимости с constexpr для функций сравнения по умолчанию:

(удалено) [class.compare.default]/4 Функция сравнения по умолчанию является constexpr-совместимой, если она удовлетворяет требованиям для функции constexpr ([dcl.constexpr]) и разрешение перегрузки не выполняется при определении того, следует ли удалить функцию, что приводит к полезный кандидат, который не является функцией constexpr.

(изменено/добавлено) [dcl.fct.def.default]/3 Функция с явным значением по умолчанию, которая не определена как удаленная, может быть объявлена ​​constexpr или consteval только в том случае, если он совместим с constexpr ([специальный], [класс.сравнить.по умолчанию]). Функция, явно дефолтная для своего первое объявление неявно встроено ([dcl.inline]) и неявно constexpr ([dcl.constexpr]), если это constexpr-совместимый удовлетворяет требованиям для функция constexpr.

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

GCC14 выполняет несколько неявных преобразований вместо одного соответствующего явного преобразования
Почему стандарт C запрещает токен частичной предварительной обработки в конце исходного файла?
Инициализация списка копирования из пустых фигурных скобок с явным конструктором по умолчанию
Соответствует ли `member_variable.a_type::b_type::static_function()` стандарту C++?
Почему неявно сгенерированный конструктор отличается от конструктора, предоставленного пользователем?
Разрешение перегрузки для оператора присваивания копирования
Каковы семантические правила VarScopedDeclarations и VarDeclaredNames в спецификации ECMAScript для непустого оператора блока?
Определяет ли стандарт, когда видны побочные эффекты создания экземпляра шаблона функции?
Гарантированно ли `uintXX_t` является беззнаковым типом `intXX_t`
Нужно ли объявлять оператор < перед вызовом std::lexicographical_compare?