哪里使用std :: variant而不是union?

44 c++ c++17

请解释之间有什么区别unionstd::variant为什么 std::variant引入标准?我们应该在什么情况下使用std::variant旧学校union

Nic*_*las 66

一般来说,variant除非出现下列情况之一,否则您应该更喜欢:

  1. 你在作弊.你正在做类型惩罚或UB的其他事情,但你希望你的编译器不会破坏你的代码.

  2. 你正在做一些C++ union允许做的伪惩罚:在布局兼容类型之间或在常见的初始序列之间进行转换.

  3. 您明确需要简单的可复制性和/或布局兼容性.variant<Ts>不需要具有任何特定布局或琐碎的可复制性.unions标准布局类型是标准布局,而union平凡可复制类型的s是可以轻易复制的.

    请注意,如果其组件类型可以轻松variant复制,则有一项建议可以轻松复制.它被提议作为针对C++ 17的缺陷报告,因此这种行为将被有效地反向移植到C++ 17中.

  4. 您需要对对象的就地切换提供低级支持.对这些东西使用内存缓冲区并不能提供琐碎的复制保证,你可以摆脱它union.

两者之间的基本区别在于variant 知道它存储的类型,同时union期望您在外部跟踪它.因此,如果您尝试访问a中的错误项variant,则会出现异常或nullptr.相比之下,使用a这样做union只是未定义的行为.

union 是一个较低级别的工具,因此只应在绝对需要较低级别时使用.

variant也有机会进行访问,这意味着你可以避免一堆if语句,你问"如果它是X型,做这个.如果它是Y型,那么,等等".

  • "仅仅是未定义的行为"并不是我经常看到的一句话.:-)*优秀*答案,但."作弊"是这里的主要动机,似乎也主要包括2和4. (14认同)
  • @CodyGray:#2和#4都是完全合法的.他们并没有真正作弊,因为他们看起来像是在作弊. (2认同)