I wonder whether we can use a union member as storage for an explicitly initialized and destructed object, such as in the following code:
struct X
{
X() { std::cout << "C"; }
~X() { std::cout << "D"; }
};
struct X_owner
{
union
{
X x; // storage for owned object
};
X_owner()
{
new (&x) X{};
}
~X_owner()
{
(&x)->~X();
}
};
int main()
{
X_owner xo;
}
The printed output is as expected only CD. Live demo: https://godbolt.org/z/M1Gov4o4d
The question is motivated by a programming assignment, where students were supposed to explicitly define storage for an object. The expected solution was a suitably aligned and sized buffer of type unsigned char or std::byte, or std::aligned_storege. However, few of them used union this way within their solutions. And I am not sure whether this is correct, though I cannot find anything wrong about it.
Note: For the sake of simplicity, I do not care about copy/move semantics in this example.