terriblememory
terriblememory

Reputation: 1754

Constructor initialization of a named union member

This code fails to compile. I get "Expected { or ," at the point indicated. (Xcode 5, so it's a reasonably complete C++11 compiler.)

Is there a way to initialize a member of the nested union in a constructor initializer list, or do I just have to do it in the constructor body?

class Foo
{
public:
    Foo(): m_bar.m_x(123) { }
private:     // ^ error here
    union
    {
        union
        {
            int m_x;
            float m_y;
        }
        m_pod;
        std::string m_name;
    };
};

Upvotes: 1

Views: 15973

Answers (1)

Dietmar Kühl
Dietmar Kühl

Reputation: 153820

Here is a rewritten version of the code fixing various issues:

  1. It gives the nested unions a constructor: like any other class type, unions need a constructor if you don't want to initialize them separately.
  2. It gives the nested union bar a destructor as its destructor is otherwise deleted due to the std::string member otherwise (and it needs to deal with the situation that the member may be of type std::string which this code doesn't). The relevant clause in the standard is 12.4 [class.dtor] paragraph 5:

    A defaulted destructor for a class X is defined as deleted if:

    - X is a union-like class that has a variant member with a non-trivial destructor,
    - ...
    
  3. It also includes the missing header <string>.

This is the code:

#include <string>
class Foo
{
public:
    Foo(): m_bar(123) { }
private:
    union bar
    {
        bar(int x): m_pod(x) {}
        bar(float y): m_pod(y) {}
        ~bar() {}
        union baz
        {
            baz(int x): m_x(x) {}
            baz(float y): m_y(y) {}
            int m_x;
            float m_y;
        }
        m_pod;
        std::string m_name;
    } m_bar;
};

Upvotes: 13

Related Questions