关于C++非POD联合体的问题

13

C++11让我们有了使用非POD类型的联合体的可能性,假设我有以下代码:

union
{
    T one;
    V two;
} uny;

在我的类中,每次只有一个成员处于活动状态,现在我的问题相当简单。

  1. uny的默认值是什么?- undefined吗?
  2. 当我的类被销毁时,哪些成员(在联合内),如果有任何成员将被销毁?
    • 假设我必须使用std::typeinfo来跟踪哪个成员是活动成员,那么我是否应该在析构函数中显式调用该成员的析构函数?
  3. 是否有人有链接到语言提案的链接,该提案将联合更改为接受非POD类型?

这个答案详细介绍了如何实际操作。 - Timmmm
3个回答

16

你主要是靠自己。标准中有一条注释解释了这一点(9.5/2):

如果联合体的任何非静态数据成员具有非平凡的默认构造函数(12.1)、拷贝构造函数(12.8)、移动构造函数(12.8)、拷贝赋值运算符(12.8)、移动赋值运算符(12.8)或析构函数(12.4),则该联合体的相应成员函数必须由用户提供,否则将为该联合体隐式删除(8.4.3)。

因此,如果任何成员构造函数都是非平凡的,你需要为联合体编写一个构造函数(如果它们都是平凡的,则默认状态将未初始化,就像 union { int; double; } 一样)。如果任何成员都有析构函数,你需要为联合体编写一个析构函数,该函数必须负责确定活动元素。

还有一个关于未限制的联合体通常用法的注释(9.5/4):

通常,必须使用显式的析构函数调用和放置new运算符来更改联合体的活动成员。


你能澄清是哪个标准规定的吗?是C++11还是普通的C++? - Pavel P

1

替代union的方法:

std::any / std::variant (C++17)

boost::any / boost::variant

这些方法允许使用非POD数据类型。


这是一个非常清晰易懂(并且三年前就提出来了)的问题,询问具有非POD类型的联合体的行为。命名一些替代方案如何回答这个问题? - Chris H
1
@ChrisH - 因为替代方案可以提供更好的解决方案。它允许比较联合行为与设计用于处理非POD数据类型的新现代特性。我不明白你关于这个问题已经三年了的观点; 如果现在可以看到它,在3或30年后,难道它不值得更新吗?请回复。 - Pietro
4
这篇帖子提出了关于非POD类型联合如何工作的非常具体的问题。如果您能说明不同选项之间的比较,那么您将对问题做出相关贡献。然而,您的回复并没有回答问题“x是如何工作的”,而是提供了“您可以使用y”这样的回答。客观地说,这不是回答所提出的问题。即使他们要求提供其他选择,这也不是一个好答案。仅仅列举替代方案,没有比较它们的功能,对任何人都没有太大的益处。 - Chris H
@ChrisH - 我想我们都能轻松地自己找到关于C++功能的文档。所以在我的答案中,我只是给出一个建议,指向一个可以处理非POD数据类型的替代选项。据我所知,在StackOverflow上这种信息不是简单的白噪声,有兴趣的人可以通过几次鼠标点击找到他需要的一切。在这里,我们不一定要重新编写所有内容,一个链接就足够了。 - Pietro
1
如果您想提供其他相关信息,尽管不是答案,您可以在评论中提供。Stack Overflow的答案应该回答问题。 - Chris H
显示剩余2条评论

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接