std::is_constant_evaluated
提供: cppreference.com
<tbody>
</tbody>
| ヘッダ <type_traits> で定義
|
||
constexpr bool is_constant_evaluated() noexcept; |
(C++20以上) | |
関数呼び出しが定数評価文脈で発生するかどうかを検出します。 呼び出しの評価が明らかに定数評価される式または変換の評価内で発生する場合は true を返し、そうでなければ false を返します。
以下の式 (結果の型への変換を含みます) は明らかに定数評価されます。
- 定数式が文法的に要求されるとき。 これには以下のようなものがあります。
- 配列の境界。
- new 式における最初以外の次元。
- ビットフィールドの長さ。
- 列挙の初期化子。
- アライメント。
- case 式。
- 非型テンプレート引数。
noexcept��定子の式。static_assert宣言の式。- 条件付き
explicit指定子の式。
- constexpr if 文の条件式。
- 即時呼び出し。
- コンセプトの定義、ネストした要件、および requires 節の制約式。
- 定数式内で使用可能な変数の初期化子。 これには以下のようなものがあります。
- constexpr 変数の初期化子。
- 参照型または const 修飾された整数型または列挙型の変数の初期化子で、初期化子が定数式のとき。
最後の2つの条件をテストするために、コンパイラは最初に初期化子の試験的な定数評価を行うことがあります。 この場合の結果に依存することは推奨されません。
int y;
const int a = std::is_constant_evaluated() ? y : 1;
// 試験的な定数評価が失敗します。 定数評価は破棄されます。
// 変数 a は 1 で動的に初期化されます。
const int b = std::is_constant_evaluated() ? 2 : y;
// std::is_constant_evaluation() == true で定数評価が成功します。
// 変数 b は 2 で静的に初期化されます。
引数
(なし)
戻り値
呼び出しの評価が明らかに定数評価される式または変換の評価内で発生する場合は true、そうでなければ false。
ノート
static_assert 宣言または constexpr if 文の条件式で直接使用されたとき、 std::is_constant_evaluated() は常に true を返します。
例
Run this code
#include <type_traits>
#include <cmath>
#include <iostream>
constexpr double power(double b, int x)
{
if (std::is_constant_evaluated() && !(b == 0.0 && x < 0)) {
// 定数評価文脈。 constexpr フレンドリーなアルゴリズムを使用します。
if (x == 0)
return 1.0;
double r = 1.0, p = x > 0 ? b : 1.0 / b;
auto u = unsigned(x > 0 ? x : -x);
while (u != 0) {
if (u & 1) r *= p;
u /= 2;
p *= p;
}
return r;
} else {
// コンパイラに計算させます。
return std::pow(b, double(x));
}
}
int main()
{
// 定数式の文脈。
constexpr double kilo = power(10.0, 3);
int n = 3;
// 定数式ではありません (定数式の文脈では
// n を右辺値に変換できないため)。
// std::pow(10.0, double(n)) と同等です。
double mucho = power(10.0, n);
std::cout << kilo << " " << mucho << "\n"; // (3)
}
出力:
1000 1000