Skip to content
Go back

C++:コンパイル時チェック

· Updated:
  • constevalな関数は必ずコンパイル時に評価される
    • 格納先が定数でない場合でもOK
    • constevalなコンストラクタを持つクラスを非定数としてもOK
    • ただし、引数に動的な値を渡すとコンパイルエラーになる
constexpr int expr(int v) {
    if (v < 0) throw "negative";
    return 0;️
}

consteval int eval(int v) {
    if (v < 0) throw "negative";
    return 0;
}

void test() {
    const int v0 = expr(0);   // OK(実行時)
    const int v1 = expr(-1);  // 実行時エラー
    constexpr int c0 = expr(0);   // OK(コンパイル時)
    constexpr int c1 = expr(-1);  // コンパイルエラー

    const int v2 = eval(0);   // OK(コンパイル時)
    const int v3 = eval(-1);  // コンパイルエラー
    constexpr int c2 = eval(0);   // OK(コンパイル時)
    constexpr int c3 = eval(-1);  // コンパイルエラー
}
  • この性質を利用して、std::formatは文字列の書式検査をコンパイル時に行っている
template <typename... Args>
struct format_string {
    consteval FormatString(const char* s) {
        // コンパイル時に書式チェックを行う
        ...
    }
};

template <typename... Args>
std::string format(FormatString<Args...> fmt, Args&&... args) {
  ...
}

void test() {
    format("{}", 0);     // OK
    format("{} {}", 0);  // コンパイルエラー

    std::string str{""};
    format(str.c_str());  // コンパイルエラー
    return 0;
}