union foo
can't initialize the bar object (how does it know which member's initializer to call?) and consequently can't initialize the std::string
s. If you want to use the bar inside of foo, then you need to manually initialize it, like so...
new (&f1.b1) bar; // Placement new
f1.b1 = b2;
// And later in code you'll have to manually destruct the bar, because
// foo doesn't know to destruct the bar either...
f1.b1.~bar();
Alternatively, you can try to roll this functionality into the union's constructors and destructors yourself.
foo() : b1() {}
// Or you construct like this, which you might need to for a non-trivial union...
// foo() { new (&b1) bar; } // Placement new.
~foo() { b1.~bar(); }
Note that copying also needs special handling.