在union中构造struct

时间:2011-03-31 09:49:40

标签: c++ struct unions

我创建了一个包含uint64_t和struct的联合。我希望union构造函数构造内部结构,但我似乎无法使它工作。以下是我尝试的几种变体:

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

2 个答案:

答案 0 :(得分:5)

你不能初始化这样的成员:你必须在detail中有一个构造函数,并从subid_u的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;
};

所以你试过了,得到了第二个错误。是的,复杂的对象在联合中是没有意义的。

而不是初始化,使用赋值(我从不通常推荐这个!)

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;
};

问题解决了??

在C ++ 0x中你可以这样做:

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;
};

答案 1 :(得分:2)

您无法使用初始化列表 - 您需要在ctor中使用赋值。

union subid_u
{
    subid_u(uint32_t gid_, uint32_t sid_) {
      detail.gid = gid_;
      detail.sid = sid_;
    }
    ...
};

这种限制是两个事实相结合的结果:

9.5 / 1摘录:

  

带有a的类的对象   非平凡的构造函数(12.1),a   非平凡的拷贝构造函数(12.8),a   非平凡的析构函数(12.4),或者   非平凡的复制赋值运算符   (13.5.3,12.8)不能成为a的成员   联盟,也不可能有这样的一系列   对象。

12.6.2 / 1摘录:

  

在构造函数的定义中   一个类,直接和。的初始化器   虚拟基础子对象和非静态对象   数据成员可以由a指定   构造函数-初始化,

因此,您只能初始化初始化列表中的直接成员变量(允许您初始化详细信息而不是详细信息的成员),并且您不能将具有构造函数的类作为联合成员。