Построение структуры внутри союза - PullRequest
2 голосов
/ 31 марта 2011

Я создал объединение, состоящее из uint64_t и структуры. Я хотел бы, чтобы конструктор объединения создавал внутреннюю структуру, но я не могу заставить ее работать. Вот несколько вариантов, которые я попробовал:

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 ]

5 голосов
/ 31 марта 2011

Вы не можете инициализировать членов-членов таким образом: вам потребуется иметь конструктор в detail и вызывать его из ctor-initializer subid_u.

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;
};
2 голосов
/ 31 марта 2011

Вы не можете использовать список инициализатора - вам нужно использовать присваивание в ctor.

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

Это ограничение является результатом объединения двух фактов:

9.5 /1 фрагмент:

Объект класса с нетривиальным конструктором (12.1), нетривиальным конструктором копирования (12.8), нетривиальным деструктором (12.4) или нетривиальнымоператор тривиального копирования (13.5.3, 12.8) не может быть членом объединения, а также не может содержать массив таких объектов.

12.6.2 / 1 фрагмент:

В определении конструктора для класса инициализаторы для прямых и виртуальных базовых подобъектов и нестатических членов данных могут быть определены ctor-initializer,

Таким образом, вы можете только инициализировать переменные прямого членав списке инициализатора (что позволяет вам инициализировать детали, но не элементы детализации), и вы не можете иметь класс с конструктором в качестве члена объединения.

...