Namespaces
Variants

consteval specifier (since C++20)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous
  • consteval - 関数が 即時関数 であることを指定します。つまり、関数へのすべての呼び出しはコンパイル時定数を生成しなければなりません

目次

説明

consteval 指定子は、関数または関数テンプレートを 即時関数 として宣言します。つまり、その関数に対するすべての 潜在的に評価される 呼び出しは、(直接的または間接的に)コンパイル時の 定数式 を生成しなければなりません。

即時関数は、 constexpr関数 であり、場合によってはその要件に従います。 constexpr と同様に、 consteval 指定子は inline を暗示します。ただし、デストラクタ、アロケート関数、またはデアロケート関数に適用することはできません。

関数または関数テンプレートの宣言で consteval を指定する場合、 constexpr も同時に指定することはできません。また、その関数または関数テンプレートの再宣言では consteval を指定する必要があります。

即時関数の、最も内側の非ブロックスコープが即時関数の 関数パラメータスコープ ではない 、または consteval if 文 のtrueブランチではない (C++23以降) 潜在的に評価される呼び出しは、定数式を生成しなければならない。このような呼び出しは 即時呼び出し として知られる。

consteval int sqr(int n)
{
    return n*n;
}
constexpr int r = sqr(100); // OK
int x = 100;
int r2 = sqr(x);            // エラー: 呼び出しが定数を生成しない
consteval int sqrsqr(int n)
{
    return sqr(sqr(n));     // この時点では定数式ではないがOK
}
constexpr int dblsqr(int n)
{
    return 2 * sqr(n);      // エラー: 外側の関数がconstevalではない
                            // かつsqr(n)は定数ではない
}

即時関数を表す 識別子式 は、即時呼び出しの部分式内、または 即時関数コンテキスト (すなわち、即時関数の呼び出しが定数式である必要がない上述の文脈)内でのみ現れます。即時関数へのポインタまたは参照は取得できますが、定数式評価から逃れることはできません:

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(); // 不適格: 即時関数へのポインタは
                        // 定数式の許可された結果ではない

注記

機能テストマクロ 規格 機能
__cpp_consteval 201811L (C++20) 即時関数
202211L (C++23)
(DR20)
consteval の上位伝播

キーワード

consteval

#include <iostream>
// この関数は、入力がコンパイル時に既知の場合、コンパイル時に評価される可能性がある
// そうでない場合は、実行時に実行される
constexpr unsigned factorial(unsigned n)
{
    return n < 2 ? 1 : n * factorial(n - 1);
}
// constevalを使用すると、関数がコンパイル時に評価されることを強制する
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); // エラー: 'argc' は定数式ではない
}

出力:

24

関連項目

constexpr 指定子 (C++11) 変数または関数の値がコンパイル時に計算可能であることを指定する
constinit 指定子 (C++20) 変数が静的初期化( zero initialization および constant initialization )を持つことを表明する
定数式 コンパイル時に評価可能な を定義する