このページはC++20に採用された言語機能の変更を解説しています。
のちのC++規格でさらに変更される場合があるため関連項目を参照してください。
概要
C++20より、共用体初期化後に別のメンバを初期化する事(アクティブメンバの切り替え)が定数式で行えるようになる。
union U {
int n;
float f;
};
constexpr int f() {
// fをアクティブメンバとして初期化
U u = { .f = 3.1415f };
// u.nへアクティブメンバを切り替え、C++17まではコンパイルエラー
u.n = 10;
return u.n;
}
int main() {
static_assert(f() == 10);
}
ただし、非アクティブメンバの読み取りは未定義動作となり、定数式では許可されていない。
この機能が必要になった背景・経緯
この提案の以前に、C++20で動的メモリ確保/解放が定数式で許可されており、各種コンテナをはじめとする標準ライブラリの多くのクラスをconstexpr
対応できるようになっていた。しかし、std::string
やstd::optional
などのクラスはその実装に共用体が用いられており、そこでは共用体のアクティブメンバの切り替えが行われていたが、それは定数式で許可されていなかった。
静的リフレクション機能を見据えてstd::string
のconstexpr
対応が急がれており、その障壁を取り除くべく、共用体のアクティブメンバ切り替えは定数式で許可される事となった。