If I have a union that contains an array of a non-trivial type (for example std::string)
using namespace std;
struct MyUnion {
union {
char c;
string s[5];
};
MyUnion() {}
~MyUnion() {}
};
Is it legal (according to the C++ standard) to only initialize a part of this array and use it?
MyUnion mu;
// construct 2 strings using placement new
new (&mu.s[0]) string();
new (&mu.s[1]) string();
// do something with the strings
do_something(mu.s[0]);
do_something(mu.s[1]);
// destruct 2 strings
mu.s[0].~string();
mu.s[1].~string();
For some reason this question has been marked as a duplicate but this question is specifically about arrays and only initializing parts of the array. The proposed duplicates do not answer this question.
Yes, but with some hassle.
Pointer arithmetic is only legal on array objects, and there is no array object at #1. Consequently,
mu.s[1]is by itself undefined behaviour.Prior to C++20, there's no way to create the array
mu.swithout also creating allstringsubobjects (and calling their constructors).With C++20, we can do
Creating a
chararray is one of the operations specified to implicitly create objects. After #2, an array ofstringis implicitly created (without creatingstringsubobjects), thus makingmu.s[1]legal.With C++23, the preferred solution is