union
とstd::variant
の違いと、なぜstd::variant
が標準に導入されたのかを説明してください。どのような状況で、旧式のunion
よりもstd::variant
を使用する必要がありますか?
一般的に、次のいずれかが発生しない限り、variant
を優先する必要があります。
あなたは浮気しています。型パニングまたはその他のUBを実行していますが、コンパイラがコードを壊さないことを望んでいます。
C++ union
sが許可されている疑似パンナリーのいくつかを実行しています:レイアウト互換型間または共通の初期シーケンス間の変換。
簡単なコピー機能やレイアウトの互換性が明示的に必要です。 variant<Ts>
には、特定のレイアウトや簡単なコピー機能は必要ありません。標準レイアウトタイプのunions
は標準レイアウトであり、簡単にコピー可能なタイプのunion
sは簡単にコピーできます。
コンポーネントタイプが簡単にコピー可能な場合、variant
を簡単にコピーできるようにする提案 があることに注意してください。 C++ 17に対する欠陥レポートとして提案されているため、この動作は事実上C++ 17にバックポートされます。
オブジェクトのインプレーススイッチングの低レベルのサポートが必要です。そのようなことのためにメモリバッファを使用しても、union
から抜け出すことができる簡単なコピーの保証は提供されません。
2つの基本的な違いは、variant
がどのタイプを格納するかを知っている一方で、union
は追跡することを期待していることです。その外部。したがって、variant
内の間違ったアイテムにアクセスしようとすると、例外またはnullptr
が発生します。対照的に、union
を使用してそうすることは、単に未定義の動作です。
union
は低レベルのツールであるため、その低レベルが絶対に必要な場合にのみ使用してください。
variant
には、訪問を行うための機構もあります。つまり、「タイプXの場合、これを行います。タイプYの場合、これを行う」という一連のif
ステートメントを避けることができます。それなど」。