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;
}