I'm attempting to implement a tagged union.
My understanding was that in a C++ union, the non-trivial (i.e. not empty) destructors of non-static members are never called, thus we have to call them ourselves. That's what I did:
#include <iostream>
class C {
public:
C() {
std::cout << "C Ctor" << std::endl;
}
~C() {
std::cout << "C Dtor" << std::endl;
}
};
class B {
public:
B() {
std::cout << "B Ctor" << std::endl;
}
~B() {
std::cout << "B Dtor" << std::endl;
}
};
struct S {
int type;
union U {
C c;
B b;
U() {
}
~U() {}
} u;
S(int type) : type(type) {
if (type == 0) {
u.c = C();
} else {
u.b = B();
}
}
~S() {
if (type == 0) {
u.c.~C();
} else {
u.b.~B();
}
}
};
int main() {
S s(0);
return 0;
}
However, the output is:
C Ctor
C Dtor
C Dtor
Meaning, the C
destructor is being called twice, instead of just once.
What is going on? And if you notice additional issues with my tagged union implementation, please point them out.
std::endl
is usually unnecessary."\n"
is just as portable and doesn't try to flush the output at every line. – Maziarstd::variant
. – Dabney