最終更新:2026-10-12
C++20 constexpr とカンマ式¶
C++那些事による constexpr と comma expr¶
C++20 は複数の新機能を導入し、コンパイル時の能力とコードの安全性をさらに強化しました。本記事では、2つの重要な変更、すなわち **constexpr 関数における例外処理**と**添字演算子におけるカンマ演算子の非推奨化**について深く掘り下げます。
注:お手軽版として、本節のコード例と関連ドキュメントは星球(ナレッジプラネット)に更新してあります。興味があればぜひご参加ください。
1. constexpr 関数での try-catch 例外処理サポートの変更¶
C++20 より前は、constexpr 関数内で try-catch ブロックを使えませんでした。この制約は、std::array のような一部の標準ライブラリコンテナのコンパイル時処理能力を妨げていました。C++20 はこれを改善し、constexpr 関数内での try-catch ブロックの使用を許可し、定数式のコンテキストではこれらの例外処理構造を無視します。定数式の計算中に例外が投げられると、コンパイラはエラーを出します。
この変更の主な目的は、標準ライブラリのコンテナ(例えば std::array)が constexpr をサポートできるようにし、将来コンパイル時により多くの例外処理をサポートする基盤を築くことです。
例:
constexpr int SafeDivide(int a, int b) {
if (b == 0) {
throw std::runtime_error("Division by zero!"); // 当除数为0时抛出异常
}
return a / b;
}
constexpr int ComputeQuotient(int x) {
try {
return SafeDivide(100, x); // 尝试除法运算
} catch (const std::runtime_error&) {
return -1; // 捕获除零异常并返回 -1
}
}
上のコードは C++20 より前ではコンパイルできません。C++20 でのこの挙動はどうなるでしょうか。次の2つの結果を予想してみてください:
2. 添字演算子におけるカンマ演算子の非推奨化¶
C++20 のもう一つの変更は、**添字演算子内でのカンマ演算子の使用を非推奨にする**ことです。初期の C++ バージョンでは、式 array[x, y] の中でカンマ演算子により y が配列やコンテナの添字として渡され、x は無視されていました。しかしこの用法はコードをわかりにくくし、将来の多次元配列の実装を妨げます。そのため C++20 からは、**添字演算子内のカンマ演算子は非推奨**となり、array[(x, y)] のように括弧で優先順位を明示する場合を除きます。
サンプルコード:
この例では、arr[(i, j)] は括号を使ってカンマ演算子の優先順位を明示し、j が配列の添字として渡されることを保証しています。C++17 では arr[i, j] が許されていましたが、C++20 ではこのような使い方をすると非推奨の警告が出ます。この方法により、コードの動作の一貫性を保ち、C++20 の新しい規格に適合できます。
カンマ演算子を使うとコンパイラは次のように警告します:
common.cc:9:10: warning: top-level comma expression in array subscript is deprecated [-Wcomma-subscript]
9 | arr[i, j] = 10; // C++17 中合法,C++20 中弃用
| ^
まとめ¶
C++20 のこれらの変更、特に constexpr 関数での例外処理サポートと添字演算子でのカンマ演算子の非推奨化は、いずれもコンパイル時の能力とコードの可読性を高めるためのものです。もしあなたのコードがこれらの古い機能に依存している場合は、C++20 の新しい規格に適応するため早めに調整することをお勧めします。
関連トピック¶
- C++20 コルーチン入門 | C++那些事
- C++20 channel 実践 | C++那些事
- C++20 Concepts コンセプト | C++那些事
- C++20 バイトオーダー endian | C++那些事
- C++20 Lambda 式(前編) | C++那些事
- C++20 モジュール Modules | C++那些事
- C++20 Ranges ライブラリ | C++那些事
- C++20 std::span の設計と落とし穴 | C++那些事
- C++20 新機能ガイド | C++那些事
- C++20 [[likely]] と [[unlikely]] | C++那些事