请解释union
和std::variant
之间的区别以及为什么std::variant
被引入标准?我们应该在什么情况下使用std::variant
而不是旧学校union
?
答案 0 :(得分:61)
一般来说,除非出现以下情况之一,否则您应该更喜欢variant
:
你在作弊。您正在进行类型惩罚或UB的其他事情,但您希望您的编译器不会破坏您的代码。
你正在做一些C ++ union
被允许做的伪惩罚:在布局兼容类型之间或在常见的初始序列之间进行转换。
您明确需要简单的可复制性和/或布局兼容性。 variant<Ts>
不需要具有任何特定布局或简单的可复制性。 unions
标准布局类型是标准布局,而union
的普通可复制类型是可以轻易复制的。
请注意a proposal to make variant
trivially copyable if its component types are trivially copyable。它被提议作为针对C ++ 17的缺陷报告,因此这种行为将被有效地反向移植到C ++ 17中。
您需要对对象的就地切换提供低级支持。使用内存缓冲区进行此类操作并不能提供琐碎的复制保证,您可以放弃union
。
两者之间的基本区别在于variant
知道它存储的类型,而union
期望您在外部跟踪它。因此,如果您尝试访问variant
中的错误项目,则会收到例外或nullptr
。相比之下,使用union
这样做只是未定义的行为。
union
是一个较低级别的工具,因此只应在绝对需要较低级别时使用。
variant
也有进行访问的机制,这意味着你可以避免在你要求的情况下发出一堆if
语句,如果它是X型,请执行此操作。如果是Y型,那么就这样做,等等#34;。