Spec-Zone.ru › C++

consteval specifier (since C++20)

  • consteval - specifies that a function is an immediate function, that is, every call to the function must produce a compile-time constant

Объяснение

Спецификатор consteval объявляет функцию или шаблон функции как немедленную функцию, то есть каждый потенциально вычисляемый вызов функции должен (прямо или косвенно) производить выражение константы на этапе компиляции.

Немедленная функция — это constexpr-функция, подчиняющаяся ее требованиям по мере необходимости. Так же, как и constexpr, спецификатор consteval подразумевает inline. Однако его нельзя применять к деструкторам, функциям выделения памяти или функциям освобождения памяти.

Функция или шаблон функции, объявляющие consteval, не могут также объявлять constexpr, и любые повторные объявления этой функции или шаблона функции также должны объявлять consteval.

Потенциально вычисляемый вызов немедленной функции, внутренний не-блочный scope которой не является scope параметра функции немедленной функции или ветви «да» в consteval-условии if(since C++23) должен производить выражение константы; такой вызов называется немедленным вызовом.

consteval int sqr(int n)
{
    return n*n;
}
constexpr int r = sqr(100); // OK
 
int x = 100;
int r2 = sqr(x);            // Error: Call does not produce a constant
 
consteval int sqrsqr(int n)
{
    return sqr(sqr(n));     // Not a constant expression at this point, but OK
}
 
constexpr int dblsqr(int n)
{
    return 2 * sqr(n);      // Error: Enclosing function is not consteval
                            // and sqr(n) is not a constant
}

Выражение идентификатора, обозначающее немедленную функцию, может появляться только внутри подвыражения немедленного вызова или внутри контекста немедленной функции (то есть контекста, упомянутого выше, в котором вызов немедленной функции не обязательно должен быть выражением константы). Указатель или ссылка на немедленную функцию могут быть взяты, но не могут выйти за пределы вычисления выражения константы:

consteval int f() { return 42; }
consteval auto g() { return &f; }
consteval int h(int (*p)() = g()) { return p(); }
constexpr int r = h();  // OK
constexpr auto e = g(); // ill-formed: a pointer to an immediate function is
                        // not a permitted result of a constant expression

Примечания

Макросы проверки наличия функций Значение Std Функция
__cpp_consteval 201811L (C++20) Немедленные функции
202211L (C++20)
(DR)
Делать consteval распространяться вверх

Ключевые слова

consteval

Пример

#include <iostream>
 
// This function might be evaluated at compile-time, if the input
// is known at compile-time. Otherwise, it is executed at run-time.
constexpr unsigned factorial(unsigned n)
{
    return n < 2 ? 1 : n * factorial(n - 1);
}
 
// With consteval we enforce that the function will be evaluated at compile-time.
consteval unsigned combination(unsigned m, unsigned n)
{
    return factorial(n) / factorial(m) / factorial(n - m);
}
 
static_assert(factorial(6) == 720);
static_assert(combination(4, 8) == 70);
 
int main(int argc, const char*[])
{
    constexpr unsigned x{factorial(4)};
    std::cout << x << '\n';
 
    [[maybe_unused]]
    unsigned y = factorial(argc); // OK
//  unsigned z = combination(argc, 7); // error: 'argc' is not a constant expression
}

Вывод:

24

См. также

constexpr specifier(C++11) указывает, что значение переменной или функции может быть вычислено на этапе компиляции
constinit specifier(C++20) утверждает, что переменная имеет статическую инициализацию, то есть нулевую инициализацию и инициализацию константой
выражение константы определяет выражение, которое может быть вычислено на этапе компиляции

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/consteval

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API