Tanımlama
Şöyle yaparız.
En büyük elemanı sığdıracak kadar bellek ayrılır. Açıklaması şöyle.
Örnek
Elimizde şöyle bir kod olsun.
Union Parametre Olarak Geçilmemeli
Açıklaması şöyle.
Aslında std::variant ile aynı şey sanırım. Elimizde bir union olsun.
Şöyle yaparız.
union AUnion {
struct CharBuf {
char *buf;
size_t len;
} charbuf;
uint8_t num;
double fp_num;
};
Bitfield ile de tanımlanabilir.union {
uint32_t cw : 13;
struct {
uint32_t setting4 : 4;
uint32_t cmd : 9;
};
} control;
Bellek AlanıEn büyük elemanı sığdıracak kadar bellek ayrılır. Açıklaması şöyle.
Tüm farklı tipler aynı adresten başlarlar. Dolayısıyla aşağıdaki önerme doğrudur.The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit- field, then to the unit in which it resides), and vice versa.
&u.num == &u.fp_num == &u.charbuf == &u
Union İçinde Nesne Varsa Constructor'ı Otomatik ÇağrılmazÖrnek
Elimizde şöyle bir kod olsun.
struct A
{
A() {std::cout << "A()\n";}
~A() {std::cout << "~A()\n";}
};
union B
{
A a;
B() {}
~B() {}
};
int main()
{
B b;
}
Açıklaması şöyle.Here, B b; prints nothing, because a is not constructed nor destructed.
If B was a struct, B() would call A(), and ~B() would call ~A(), and you wouldn't be able to prevent that.
Union İçindeki Sadece Tek Bir Alana Default Value Atanabilir
Örnek
Şu kod derlenmez
union U {
int a = 1;
int b = 0;
};
U u; // what's the value of u.a ? what's the value of u.b ?
assert(u.a != u.b); // knowing that this assert should always fail.
Şu kod derlenir
struct A
{
int x;
};
union U
{
A a; // this is fine, since you did not explicitly defined a
// default constructor for A, the compiler can skip
// initializing a, even though A has an implicit default
// constructor
int b = 0;
};
Açıklaması şöyle.
The following is not a valid fragment (because the union type is not visible within function f)Şu kod yanlış.
struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 * p1, struct t2 * p2)
{
if (p1->m < 0)
p2->m = -p2->m;
return p1->m;
}
int g()
{
union {
struct t1 s1;
struct t2 s2;
} u;
/* ... */
return f(&u.s1, &u.s2);
}
Discriminated UnionAslında std::variant ile aynı şey sanırım. Elimizde bir union olsun.
struct Result {
union {
int i_res;
double d_res;
};
enum { IS_INT, IS_DOUBLE } u_tag;
Result(int i) : i_res{i}, u_tag{IS_INT} {}
Result(double d) : d_res{d}, u_tag{IS_DOUBLE} {}
auto& operator=(int i)
{ i_res = i; u_tag = IS_INT; return *this; }
auto& operator=(double d)
{ d_res = d; u_tag = IS_DOUBLE; return *this; }
};
Şöyle yaparız.std::function<Result(double)> cb;
cb = myfunction;
auto r = cb(1.0);
assert(r.u_tag == Result::IS_INT);
std::cout << r.i_res << '\n';
Hiç yorum yok:
Yorum Gönder