11

間に実質的な違いがあるシナリオを少なくとも 1 つ提案できますか?

union {
T var_1;
U var_2;
}

var_2 = reinterpret_cast<U> (var_1)

?

これについて考えれば考えるほど、少なくとも実際的な観点からは、それらは同じものに見えます。

私が見つけた違いの 1 つは、ユニオン サイズがサイズの点で最大のデータ型として大きい一方で、この投稿で説明されている reinterpret_cast は切り捨てにつながる可能性があるため、単純な古い C スタイルのユニオンは新しいものよりもさらに安全であるということです。 C++ キャスト。

この 2 の違いを概説できますか?

4

4 に答える 4

5

union適切なと (仮定しましょう) 適切で安全な の間には、いくつかの技術的な違いがありますreinterpret_cast。しかし、克服できないこれらの違いは考えられません。

私の意見では、オーバーを好む本当の理由は技術的なものではありません。資料用です。unionreinterpret_cast

ワイヤ プロトコルを表現するための一連のクラスを設計しているとします (これが、最初に型パニングを使用する最も一般的な理由だと思います)。ワイヤ プロトコルは、多くのメッセージ、サブメッセージ、およびフィールドで構成されています。msg タイプ、seq# など、これらのフィールドの一部が共通している場合、共用体を使用すると、これらの要素を簡単に結び付けることができ、ネットワーク上でプロトコルがどのように表示されるかを正確に文書化するのに役立ちます。

Usingreinterpret_castも明らかに同じことを行いますが、実際に何が起こっているかを知るには、あるパケットから次のパケットに進むコードを調べる必要があります。a を使用するunionと、ヘッダーを見て、何が起こっているかを把握できます。

于 2013-07-29T12:39:38.043 に答える
1

C++11 では、union はclass typeであり、重要なメンバー関数を持つメンバーを保持できます。あるメンバーから別のメンバーに単純にキャストすることはできません。

§ 9.5.3

[ 例: 次の共用体を考えてみましょう:

union U {
int i;
float f;
std::string s;
};

std::string (21.3) はすべての特別なメンバー関数の非自明なバージョンを宣言するため、U には暗黙的に削除されたデフォルト コンストラクター、コピー/移動コンストラクター、コピー/移動代入演算子、およびデストラクターがあります。U を使用するには、これらのメンバー関数の一部またはすべてをユーザーが提供する必要があります。— 終了例 ]

于 2013-07-29T12:23:13.033 に答える
-1

実用的な観点からは、少なくとも実際の非架空のコンピューターでは、それらはおそらく 100% 同一です。ある型のバイナリ表現を取得し、それを別の型に詰め込みます。

言語弁護士の観点からすると、使用reinterpret_castは場合によっては明確に定義されており (たとえば、整数変換へのポインター)、それ以外の場合は実装固有です。

一方、ユニオン型のパニングは、常に非常に明確に未定義の動作です (ただし、未定義は必ずしも「機能しない」という意味ではありません)。標準では、非静的データ メンバーの最大 1 つの値をいつでも共用体に格納できると規定されています。これは、設定した場合var1var1有効ですが、そうでvar2はないことを意味します。
ただし、var1var2は同じメモリ位置に格納されているため、もちろん、任意の型を好きなように読み書きすることができます。格納サイズが同じであると仮定すると、ビットが「失われる」ことはありません。

于 2013-07-29T12:36:39.433 に答える