サーチ…
備考
組合は非常に便利なツールですが、いくつかの重要な注意点があります:
最も最近変更されたメンバーではないユニオンの要素にアクセスすることは、C ++標準に従って未定義の動作です。多くのC ++コンパイラはこのアクセスを明確な方法で許可していますが、これらは拡張であり、コンパイラ間で保証することはできません。
std::variant
(C ++ 17以降)はユニオンと似ていますが、現在の内容を示しています(可視状態の一部は、特定の時点で保持されている値の型です。そのタイプに)。実装では、必ずしも異なるサイズのメンバーを同じアドレスに揃える必要はありません。
基本的な連合機能
共用体は、すべての構成要素が重複するメモリーを占有する特殊な構造体です。
union U {
int a;
short b;
float c;
};
U u;
//Address of a and b will be equal
(void*)&u.a == (void*)&u.b;
(void*)&u.a == (void*)&u.c;
//Assigning to any union member changes the shared memory of all members
u.c = 4.f;
u.a = 5;
u.c != 4.f;
典型的な用途
共用体は、混合データ型を実装する場合など、排他的なデータのメモリ使用を最小限に抑えるのに便利です。
struct AnyType {
enum {
IS_INT,
IS_FLOAT
} type;
union Data {
int as_int;
float as_float;
} value;
AnyType(int i) : type(IS_INT) { value.as_int = i; }
AnyType(float f) : type(IS_FLOAT) { value.as_float = f; }
int get_int() const {
if(type == IS_INT)
return value.as_int;
else
return (int)value.as_float;
}
float get_float() const {
if(type == IS_FLOAT)
return value.as_float;
else
return (float)value.as_int;
}
};
未定義の動作
union U {
int a;
short b;
float c;
};
U u;
u.a = 10;
if (u.b == 10) {
// this is undefined behavior since 'a' was the last member to be
// written to. A lot of compilers will allow this and might issue a
// warning, but the result will be "as expected"; this is a compiler
// extension and cannot be guaranteed across compilers (i.e. this is
// not compliant/portable code).
}
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow