struct variant
{
union variants
{
std::string s;
int i;
uint8_t none;
variants() : none(0){}
variants(const std::string & s) : s(s){} // option A
~variants(){}
};
enum class Tag {STR,INT,NONE};
variant() = default;
variant(const std::string & s)
: tag(Tag::STR), v(s) // option A
{
// new (&v.s) std::string(s); // option B
}
variant(const int i)
: tag(Tag::INT)
{
v.i = i;
}
~variant()
{
if (tag == Tag::STR)
{
using namespace std;
v.s.~string();
}
}
variants v;
Tag tag = Tag::NONE;
};
is it undefined behavior to have a constructor in the union that directly constructs a certain member (with non trivial special member functions) as in option A in the code snippet above or must one always use the placement new operator as in option B?
Edit: Not sure how or where does the suggested duplicate fits? I'm asking about strictly adding a constructor to the union definition itself (please check the comments 'option A' in the code snippet)
Edit: The answer to my question is in the second duplicate not the first one (Do unrestricted unions require placement new and a constructor definition?)