1
tt(Union)'s copy and move constructors suffer from the same problem as
2
tt(Union)'s destructor does: the union does not know which is its currently
3
active field. But again: tt(Data) does, and by defining `extended' copy and
4
move constructors, also receiving a tt(Tag) argument, these extended
5
constructors can perform their proper initializations. The tt(Union)'s copy-
6
and move-constructors are deleted, and extended copy- and move constructors
9
Union(Union const &other) = delete;
10
Union &operator=(Union const &other) = delete;
12
Union(Union const &other, Tag tag);
13
Union(Union &&tmp, Tag tag);
16
Shortly we'll encounter a situation where we must be able to initialize a
17
block of memory using an existing tt(Union) object. This task can be performed
18
by tt(copy) members, whose implementations are trivial, and which may be used
19
by the above constructors. They can be declared in tt(Union)'s private
20
section, and have identical parameter lists as the above constructors:
22
void copy(Union const &other, Tag tag);
23
void copy(Union &&other, Tag tag);
26
The constructors merely have to call these tt(copy) members:
28
inline Data::Union::Union(Union const &other, Tag tag)
33
inline Data::Union::Union(Union &&tmp, Tag tag)
35
copy(std::move(tmp), tag);
39
Interestingly, no `initialization followed by assignment' happens here:
40
tt(d_union) has not been initialized in any way by the the time we reach the
41
statement blocks of the above constructors. But upon reaching the statement
42
blocks, tt(d_union) memory is merely raw memory. This is no problem, as the
43
tt(copy) members use placement new to initialize the tt(Union)'s memory:
45
void Data::Union::copy(Union const &other, Tag otag)
50
new (this) string(other.u_string);
53
void Data::Union::copy(Union &&tmp, Tag tag)
58
new (this) string(std::move(tmp.u_string));