1. ホーム
  2. c++

consteval関数は、関数の引数に依存するテンプレートパラメータを許容するか?

2023-08-24 13:54:48

質問

C++17では、このコードは不正です。

constexpr int foo(int i) {
    return std::integral_constant<int, i>::value;
}

というのも、たとえ foo がコンパイル時に評価できたとしても、コンパイラは実行時にそれを実行するための命令を生成する必要があるため、テンプレートのインスタンス化が不可能になるからです。

C++20では consteval 関数が追加されます。これはコンパイル時に評価される必要があるため、実行時の制約がなくなるはずです。このコードは合法になるということでしょうか?

consteval int foo(int i) {
    return std::integral_constant<int, i>::value;
}

どのように解決するのですか?

いいえ。

この論文がどんな変更を伴うものであれ、それはほとんど この時点では であるにせよ、非テンプレート関数定義が一度だけ型付けされるという事実を変更することはできません。さらに、もしあなたの提案したコードが合法であるなら、私たちはおそらく型 std::integral_constant<int, i> という型の変数を宣言する方法を見つけることができると思われますが、これは ODR の観点から非常に禁止されているように感じられます。

この論文はまた、その例の1つで、パラメータがコア定数式として扱われることを意図していないことを示しています。

consteval int sqrsqr(int n) {
  return sqr(sqr(n)); // Not a constant-expression at this  point,
}                     // but that's okay.


要するに、型付けの不一致の可能性から、関数のパラメータは決して定数式にはなりません。