【问题标题】:Member of Union has User-Defined Constructor联盟成员具有用户定义的构造函数
【发布时间】:2016-10-17 13:55:29
【问题描述】:

对于以下代码:

class Foo{
    int foo;
public:
    Foo() : foo(13) {}
    int getFoo() const { return foo; }
};

union Bar{
    Foo fBar;
    double dBar;
};

我相信这在 C++ 中是完全合法的。 http://en.cppreference.com/w/cpp/language/union#Explanation 说:

如果两个联合成员是标准布局类型,则在任何编译器上检查它们的公共子序列是明确定义的

因此in gcc I can do this:

Bar bar = { Foo() }

当我在 Visual Studio 2008 中尝试这个时,我得到了错误:

错误 C2620:union Bar 的成员 Bar::fBar 具有用户定义的构造函数或重要的默认构造函数

Error C2620 状态:

联合成员不能有默认构造函数。

这里发生了什么?这曾经是 C++ 的要求吗,我认为标准布局是唯一的要求?有解决办法吗?

【问题讨论】:

  • VS2008 不包含 C++11 编译器。如果要使用 C++11 中引入的语言功能,则需要升级
  • 如果您想要获得最高的 C++11 一致性,我会选择 2015 更新 3。
  • @CaptainObvlious 这不是 C++11 的功能,并且错误仍然列在 Visual Studio 2013 中:msdn.microsoft.com/en-us/library/43ae0055(v=vs.120).aspx
  • @NathanOliver 这不是 C++11 的功能,并且错误仍然列在 Visual Studio 2013 中:msdn.microsoft.com/en-us/library/43ae0055(v=vs.120).aspx
  • @JonathanMee Unions 确实从 C++98/03 更改为 C++11。在他们必须只有 POD 对象之前。现在它们被扩展了。另请注意,MSVS2013 仍然缺少 C++11 功能。请参阅this,其中有 Unrestricted union

标签: c++ visual-studio-2008 unions default-constructor standard-layout


【解决方案1】:

在 C++98/03 中,9.5 中规定的 C++ 标准

[...]如果一个 POD-union 包含多个 POD-structs,它们共享一个共同的初始序列 (9.2),并且如果此 POD-union 类型的对象包含一个 POD-structs,则允许检查任何 POD 结构成员的公共初始序列;[...]

这在 C++11 中被更改为

[...]如果一个标准布局联合包含多个标准布局结构,它们共享一个共同的初始序列 (9.2),并且如果此标准布局联合类型的对象包含标准布局结构之一,允许检查任何标准布局结构成员的公共初始序列;[...]

因此,在 C++11 之前,您只能在联合中使用 POD 类型,这意味着 MSVS 2008 给了您正确的错误。为了使用新类型的联合,您需要获得支持该更改的 MSVS 版本。从this MSDN article,我们可以在不受限制的联合部分看到该更改直到2015版才进行。

您将不得不升级或将课程更改为POD type

【讨论】:

  • 那么看来en.cppreference.com 有问题吗?所以我在问题中的引用应该包含在 C++11 块中?
  • @JonathanMee 看起来那样。要点是正确的,但术语发生了变化。
猜你喜欢
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 2012-10-17
  • 2018-07-30
  • 2015-08-10
  • 1970-01-01
  • 2011-11-07
  • 2018-10-28
相关资源
最近更新 更多