Функция-член consteval разрешена?

У меня есть код C++20/23 :

#include <cstddef>

template <size_t N>
class Foo {
    public:
        consteval size_t size() noexcept { return N; }

        size_t real_size() {
            return size() - 1;
        }
};

int main(int argc, char* argv[]) {
    Foo<5> foo;
    return foo.real_size();
}

clang 10 и gcc 14.1 могут скомпилировать его без каких-либо ошибок/предупреждений.

Однако clang 14-18.1 выдает ошибку:

<source>:9:20: error: call to consteval function 'Foo<5>::size' is not a constant expression
    9 |             return size() - 1;
      |                    ^
<source>:15:16: note: in instantiation of member function 'Foo<5>::real_size' requested here
   15 |     return foo.real_size();
      |                ^
<source>:9:20: note: implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function
    9 |             return size() - 1;
      |                    ^
1 error generated.

Какие компиляторы соответствуют стандартам C++20 и C++23? Почему?

Скомпилируйте с помощью staticDemo.

Jarod42 25.07.2024 17:22
Стоит ли изучать 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
1
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это еще один пример P2280, который clang еще не реализован.

Исходное требование C++20 для основных константных выражений заключалось в том, что вам не разрешалось выполнять вычисления (из C++20 [expr.const]):

this, за исключением функции constexpr или конструктора constexpr, который оценивается как часть e;

Который был изменен на (C++23 [expr.const]):

this ([expr.prim.this]), за исключением

  • в функции constexpr ([dcl.constexpr]), которая оценивается как часть E или
  • при появлении в качестве постфиксного выражения неявного или явного выражения доступа к члену класса ([expr.ref]);

Вызов size() (который неявно является this->size(), поскольку это нестатическая функция-член) должен быть постоянным выражением (потому что это consteval). Это исходное правило отвергло оценку this, но новое больше не делает этого. Таким образом, выражение this->size() удовлетворяет правилам основного константного выражения.

Но this — это не постоянное выражение, верно? Не в функции, отличной от constexpr.

Nicol Bolas 25.07.2024 17:29

@NicolBolas Да, именно поэтому изначально оно было отклонено.

Barry 25.07.2024 17:30

возможно, «вам не разрешалось вычислять [...] это, если только [...]» -> «как часть основного константного выражения вам не разрешалось…»

463035818_is_not_an_ai 25.07.2024 17:42

@Barry C++23 позволяет это, потому что this->some_member(_function) считается postfix-expression? И такой postfix-expression «неявно» обращается к члену класса (Нет? думал, что член класса относится к статической переменной-члену в классе, нет?)

HCSF 25.07.2024 17:45

похоже, что class member здесь относится к любой статической и нестатической переменной-члену и функции-члену? по сути, это означает, что любая неявная или явная this-> или obj., за которой следует consteval функция-член (или функция класса), считается core constant expression?

HCSF 25.07.2024 17:54

@463035818_is_not_an_ai Спасибо, сделал что-то подобное

Barry 25.07.2024 17:54

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