1

对于以下代码:

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说:

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

因此在 gcc 中我可以这样做

Bar bar = { Foo() }

当我在 Visual Studio 2008 中尝试此操作时,出现错误:

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

错误 C2620指出:

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

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

4

1 回答 1

2

在 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 版本。从这篇 MSDN 文章中 ,我们可以在Unrestricted unions部分看到,直到 2015 版才进行该更改。

您将不得不升级或将类更改为POD 类型

于 2016-10-17T15:11:47.203 回答