名前空間
変種
操作

std::is_constant_evaluated

提供: cppreference.com
< cpp‎ | types
 
 
 
型サポート
型の性質
(C++11)
(C++11)
(C++14)
(C++11)
(C++11)(C++20未満)
(C++11)(C++20で非推奨)
(C++11)
型特性定数
メタ関数
(C++17)
定数評価文脈
is_constant_evaluated
(C++20)
サポートされている操作
関係と性質の問い合わせ
型変更
(C++11)(C++11)(C++11)
型変換
(C++11)
(C++11)
(C++17)
(C++11)(C++20未満)(C++17)
 
ヘッダ <type_traits> で定義
constexpr bool is_constant_evaluated() noexcept;
(C++20以上)

関数呼び出しが定数評価文脈で発生するかどうかを検出します。 呼び出しの評価が明らかに定数評価される式または変換の評価内で発生する場合は true を返し、そうでなければ false を返します。

以下の式 (結果の型への変換を含みます) は明らかに定数評価されます。

  • 定数式が文法的に要求されるとき。 これには以下のようなものがあります。
  • 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 を返します。

[編集]

#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