【问题标题】:Stuff a class with user-defined constructors into a union将具有用户定义构造函数的类填充到联合中
【发布时间】:2010-09-27 12:22:46
【问题描述】:
class Foo {
    Foo(int val) { /* Do some initialization */ }
    Foo() { /* Do nothing */ }
};
union Bar {
    Foo foo;
};

该代码会产生此错误:

错误 C2620:联合 'Bar' 的成员 'Bar::foo' 具有用户定义的构造函数或非平凡的默认构造函数

我理解如果构造函数确实做了什么你会抛出那个错误,但是这里的构造函数没有参数并且什么都不做。有什么办法可以把这个类塞进一个工会?我不得不一直求助于char foo[sizeof(Foo)],并且想要一个更清洁的解决方案。

【问题讨论】:

    标签: c++ constructor unions


    【解决方案1】:

    最初来自这个问题:

    Initializing a union with a non-trivial constructor:

    来自 C++03,9.5 联合,第 162 页

    联合可以具有成员函数(包括构造函数和析构函数),但不能具有虚拟 (10.3) 函数。联合不应有基类。联合不应用作基类。具有非平凡构造函数 (12.1)、非平凡复制构造函数 (12.8)、非平凡析构函数 (12.4) 或非平凡的类的对象复制赋值运算符(13.5.3、12.8)不能是联合的成员,也不能是此类对象的数组

    所以,你的班级被禁止成为工会的成员。

    【讨论】:

      【解决方案2】:

      这在 C++03 标准中是不允许的。

      如果联合中允许具有用户定义的默认构造函数的对象,编译器将无法决定使用哪个构造函数,因为它们都引用相同的内存位置。因此,具有用户定义构造函数的对象不允许在联合中。

      编译器会忽略你的构造函数不做任何事情的事实,因为它可能在联合之外的其他地方定义。

      C++0x constructor() = default; 可能会侥幸成功

      【讨论】:

      • 真可惜……如果我只使用“Foo() = default”,它可以工作,但如果我添加另一个构造函数以及显式默认值,它会再次抱怨。
      • constructor() = default 在 VS 2013 中为我解决了这个问题,尚未测试 GCC 或 Xcode。
      【解决方案3】:

      标准专家可能会比我更准确地回答这个问题,但如果我没记错的话,工会成员必须是 POD 类型的。

      如果您想在联合中使用非 POD 类,请使用 boost::variant

      【讨论】:

        【解决方案4】:

        如果您的类具有用户定义的构造函数、析构函数或复制构造函数,或赋值运算符,则它不能位于联合内部。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多