Unrestricted union for non-POD members

Question | Jan 7, 2017 | nextptr 

A union, prior to C++11, could only have class/struct members that had trivial constructors. This restriction has been removed in C++11. The unrestricted unions of C++11 can have data members that are not plain-old-data (POD) type .

enter image description here

Typically unions are used in a struct with an enum to store the data and its type. We have an example code below that defines an anonymous unrestricted union of 2 non-POD types (Tiger and Lion). Compiler would synthesize non-trivial special methods (e.g default constructor) for Tiger and Lion because they have std::string and std::vector data members:

// Tiger and Lion are non-POD types
struct Tiger {
  std::vector<std::string> habitats;
  // .. more attributes

struct Lion {
  std::string habitat;
  // .. more attributes

Note that If a struct contains a union that has a non-POD type, e.g BigCat below, the C++ compiler marks the special methods (e.g default constructor and destructor) deleted. That means at least a user-defined default constructor and destructor are must for BigCat to be of any use. A copy-constructor, copy-assignment-operator, move-constructor, move-assignment-operator might also have to be written depending on requirement.

// enum to store the kind of BigCat
enum class BigCatType { Tiger, Lion  };

// struct BigCat has the unrestricted union
struct BigCat {

 // Default constructor must be defined 
 // Note use of placement-new to call union member constructors 
  BigCat(BigCatType ct):bigCatType(ct) {
    if( bigCatType == BigCatType::Tiger )
       new (&tiger) Tiger();
    else if(bigCatType == BigCatType::Lion)
       new (&lion) Lion();

  // Destructor must be defined 
  ~BigCat() {
     /*  call tiger.~Tiger() or lion.~Lion() 
         depending upon bigCatType */

  // Assignment operator
  const BigCat& operator = (const BigCat& bc) {
      /* ... can be implemented by 
             copying to tiger or lion depending upon bigCatType .. */

  BigCatType bigCatType;

  union {
    Tiger tiger; // Only since C++11
    Lion lion; // Only since C++11


Following code uses BigCat. A BigCat instance, bigCat, is created inside a block to make sure that it is destroyed before std::cout << tiger.habitats.front(); executes:

Tiger tiger;
Lion lion;
lion.habitat = "Africa";
    // inside a block
    BigCat bigCat(BigCatType::Tiger);    

    tiger = bigCat.tiger;

    // lion is copied to bigCat.lion
    bigCat.lion = lion;
// Out of block. Print tiger's first habitat
std::cout << tiger.habitats.front();

What would be printed by or be the result of above code?