Reputation: 4592
I have created a union comprising a uint64_t and a struct. I would like the union constructor to construct the inner struct but I can't seem to get it working. Here's a couple of variations I have tried:
union subid_u
{
inline subid_u(uint32_t gid_, uint32_t sid_)
: detail.gid(gid_), detail.sid(sid_) {}
struct detail_t
{
uint32_t gid;
uint32_t sid;
};
detail_t detail;
uint64_t subscriptionID;
};
//main.cpp: In constructor 'subid_u::subid_u(uint32_t, uint32_t)':
//main.cpp:7: error: expected `(' before '.' token
//main.cpp:7: error: expected `{' before '.' token
union subid_u
{
inline subid_u(uint32_t gid_, uint32_t sid_)
: detail(gid_, sid_) {}
struct detail_t
{
inline detail_t(uint32_t g, uint32_t s)
: gid(g), sid(s) {}
uint32_t gid;
uint32_t sid;
};
detail_t detail;
uint64_t subscriptionID;
};
//main.cpp:18: error: member 'subid_u::detail_t subid_u::detail' with constructor not allowed in union
Upvotes: 2
Views: 2612
Reputation: 385134
You can't initialise members of members like that: you'd have to have a constructor in detail
and invoke that from subid_u
's ctor-initialiser.
union subid_u
{
inline subid_u(uint32_t gid, uint32_t sid) : detail(gid, sid) {}
struct detail_t
{
detail_t(uint32_t gid, uint32_t sid) : gid(gid), sid(sid) {}
uint32_t gid;
uint32_t sid;
};
detail_t detail;
uint64_t subscriptionID;
};
So you tried that, and got your second error. Yes, it doesn't make sense for a complex object to be in a union.
Instead of initialisation, use assignment (and I'd never usually recommend this!)
union subid_u
{
inline subid_u(uint32_t gid_, uint32_t sid_) {
detail.gid = gid_;
detail.sid = sid_;
}
struct detail_t
{
uint32_t gid;
uint32_t sid;
};
detail_t detail;
uint64_t subscriptionID;
};
Problem solved...?
In C++0x you'll be able to do this:
union subid_u
{
inline subid_u(uint32_t gid, uint32_t sid) : detail{gid, sid} {}
struct detail_t
{
uint32_t gid;
uint32_t sid;
};
detail_t detail;
uint64_t subscriptionID;
};
Upvotes: 5
Reputation: 91260
You can't use the initializer list - you'll need to use assignment in the ctor.
union subid_u
{
subid_u(uint32_t gid_, uint32_t sid_) {
detail.gid = gid_;
detail.sid = sid_;
}
...
};
This limitation is a result of combining two facts:
9.5/1 snippet:
An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects.
12.6.2/1 snippet:
In the definition of a constructor for a class, initializers for direct and virtual base subobjects and nonstatic data members can be specified by a ctor-initializer,
So, you can only initialize direct member variables in an initializer list (allowing you to initialize detail but not detail's members), and you cannot have a class with a constructor as a union member.
Upvotes: 2