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

发布于 2024-11-07 03:16:20 字数 1585 浏览 0 评论 0原文

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

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


令人沮丧的是,如果我向 p1 和 p2 结构添加标签,代码将编译,但 f 和 p2 结构体将被编译。 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'
}


有什么办法可以让这项工作以某种方式进行吗?

I desperately need to find a solution for the following problem:

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



It's frustrating that if I add tags to p1 and p2 structs, the code will compile, but the f & ff members would not be accessible:

...
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'
}



Is there any way to make this work somehow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枯叶蝶 2024-11-14 03:16:20

正如@Als所说,union不能将非POD定义为成员数据,有一种替代方法。您仍然可以定义指向非 POD 的指针作为联合的成员数据。

所以这是允许的:

union
{
   struct
   {
      Flags<4096> *pf; //pointer to non-POD
   }p1;
   struct 
   {
      Flags<16384> *pff; //pointer to non-POD
   }p2;
}parts;

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

As @Als said, union cannot define non-POD as member data, there is one alternative. You can still define a pointer to the non-POD as member data of the union.

So this is allowed:

union
{
   struct
   {
      Flags<4096> *pf; //pointer to non-POD
   }p1;
   struct 
   {
      Flags<16384> *pff; //pointer to non-POD
   }p2;
}parts;

But then Boost.Variant is a better alternative.

破晓 2024-11-14 03:16:20

当前的 C++ 标准不允许联合内有非 POD 类型。因此,您会从 gcc 中收到此编译器错误。
您应该使用 boost::variant,而不是使用 C 联合。请在此处查看文档。

添加到上面:
新的 C++ 标准 (C++0x) 添加了一个名为 无限制的Unrestricted Unions,支持将非POD类型存储到Union中。

Current C++ standard does not allow non-POD types inside unions. Hence you get this compiler error from gcc.
Instead of using C unions, you should use boost::variant. Check the doccumentation here.

To add to the above:
The new C++ standard(C++0x) adds a new feature called as Unrestricted Unions, which supports storing non-POD types to a Union.

時窥 2024-11-14 03:16:20

C++ 标准 2003 不允许这样做(从标准 9.5 开始):

一个类的对象
非平凡的构造函数(12.1),a
非平凡的复制构造函数(12.8),
非平凡的析构函数(12.4),或
重要的复制赋值运算符
(13.5.3, 12.8) 不能是以下组织的成员
union,也不能是这样的数组
对象。

但是C++0x允许这样做,但是,您需要定义自己的构造函数,因为如果您不定义自己的构造函数,默认构造函数将被声明为删除。

从 N3291 9.5 开始:

如果a的任何非静态数据成员
union 有一个不平凡的默认值
构造函数(12.1)、复制构造函数
(12.8)、移动构造函数 (12.8)、复制
赋值运算符 (12.8)、移动
赋值运算符(12.8),或
析构函数(12.4),相应的
工会的成员职能必须是
用户提供的,否则它将是隐式的
为联合删除了 (8.4.3)。

其他人建议使用 Boost.Variant。对于简单的修复,只需从 Flag 类中删除构造函数即可。尽管每次初始化 union 对象时都需要手动初始化它,但这不会造成混淆,因为 union 本质上是 C 功能。

C++ standard 2003 doesn't allow this (from Standard 9.5):

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.

But C++0x allows it, however, you need to define your own constructor because default constructor will be declared as deleted if you don't define your own.

From N3291 9.5:

If any non-static data member of a
union has a non-trivial default
constructor (12.1), copy constructor
(12.8), move constructor (12.8), copy
assignment operator (12.8), move
assignment operator (12.8), or
destructor (12.4), the corresponding
member function of the union must be
user-provided or it will be implicitly
deleted (8.4.3) for the union.

Other people has suggested Boost.Variant. For simple fix, just remove the constructor from Flag class. Though you need to initialize it manually whenever you initialize the union object, it won't be confusing because union is essentially a C feature.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文