1

I am using the same qualifier for a union inside class and for a parameter to this class constructor, like this:

class A
{
    union 
    {
        C y;
        D z;
    }
    x;
public:
    A(B x);
}

I want to use y's constructor C(B q);

I attempted this:

A(B x)
    :   x.y(x)
{
}

But in this case it seems the compiler (or at least the IDE, in this case VS15) can't deal with name conflict smart, as it would if the case was simpler (ie. something like x(x)).

I had to resort to:

A(B x)
{
    this->x.y = x;
}

When trying to use this pointer in initializer list, I get error "expected an identifier".

Is there any way to achieve the effect of this line in initialization list?

szpanczyk
  • 486
  • 4
  • 15

1 Answers1

4

You need to give your union a constructor, and thus also a name:

class A
{
    union X
    {
        C y;
        D z;

        X(B b) : y(b) {}

        // other operations
    };

    X x;

public:
    A(B b) : x(b) {}
};
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Technically speaking, [uniform initialization](http://stackoverflow.com/a/13056662) might avoid the need for constructor in that case. (I am not saying that it is a good practice though.) – AlexD Jan 15 '17 at 02:18
  • 1
    @AlexD: Why not post that as an answer :-) (But note that aggregate initialization for unions is only available for the first variant member.) – Kerrek SB Jan 15 '17 at 02:19
  • by the way, is it actually advisable? cause I don't even know why I want to do that – szpanczyk Jan 15 '17 at 02:24
  • @KerrekSB I just meant to say that "_you need to give your union a constructor_" is a bit too restrictive. Sure, as the linked answer suggests, it is a limited approach. And I doubt if it is a good practice. Rather something to mention for completeness :-). – AlexD Jan 15 '17 at 02:29