...在联合问题中不允许使用构造函数

Rya*_*yan 8 c++ gcc struct visual-c++ unions

我迫切需要找到解决以下问题的方法:

namespace test
{
    template <int param = 0> struct Flags
    {
        int _flags;

        Flags()
        {
            _flags = 0;
        }

        Flags(int flags)
        {
            _flags = flags;
        }

        void init()
        {

        }
    };

    union example
    {
        struct
        {
            union
            {
                struct
                {
                    Flags<4096> f;
                }p1; //error: member 'test::example::<anonymous struct>::<anonymous union>::<anonymous struct> test::example::<anonymous struct>::<anonymous union>::p1' with constructor not allowed in union

                struct 
                {
                    Flags<16384> ff;
                }p2; //error: member 'test::example::<anonymous struct>::<anonymous union>::<anonymous struct> test::example::<anonymous struct>::<anonymous union>::p2' with constructor not allowed in union
            }parts;

            byte bytes[8];
        }data;

        int data1;
        int data2;
    }
}
Run Code Online (Sandbox Code Playgroud)


令人沮丧的是,如果我向p1和p2结构添加标签,代码将编译,但f&ff成员将无法访问:

...
struct p1
{
    Flags<4096> f;
};

struct p2
{
    Flags<4096> ff;
};
...

void test()
{
    example ex;
    ex.data.bytes[0] = 0; //Ok
    ex.data.parts.p1.f.init(); //error: invalid use of 'struct test::example::<anonymous struct>::<anonymous union>::p1'
}
Run Code Online (Sandbox Code Playgroud)


有什么方法可以以某种方式使这项工作?

Naw*_*waz 9

正如@Als所说,联盟不能将非POD定义为成员数据,还有一种选择.您仍然可以将指向非POD的指针定义为union的成员数据.

所以这是允许的:

union
{
   struct
   {
      Flags<4096> *pf; //pointer to non-POD
   }p1;
   struct 
   {
      Flags<16384> *pff; //pointer to non-POD
   }p2;
}parts;
Run Code Online (Sandbox Code Playgroud)

但随后Boost.Variant是一个更好的选择.


Alo*_*ave 7

当前的C++标准不允许联合内部的非POD类型.因此,您从gcc获得此编译器错误.
而不是使用C联合,你应该使用boost::variant.在这里检查文档.

添加到上面:
新的C++标准(C++ 0x)添加了一个名为Unrestricted Unions的新功能,它支持将非POD类型存储到Union.