std :: variant和boost :: variant之间有什么区别?

时间:2016-10-23 09:19:38

标签: c++ boost c++17 variant boost-variant

在这个问题的answer中:

What is the equivalent of boost::variant in the C++ standard library?

提到boost::variantstd::variant有所不同。

  • 就使用这些课程的人而言,有什么区别?
  • 委员会表达了采用std::variant这些差异的动机是什么?
  • 在使用其中任何一个进行编码时应该注意什么,以保持与切换到另一个的最大兼容性?

(动机是在前C ++ 17代码中使用boost::variant

3 个答案:

答案 0 :(得分:17)

  • 作业/进驻行为:

    • boost::variantallocate memory when performing assignment进入直播variant。有a number of rules that govern when this can happen,因此boost::variant是否会分配内存取决于它实例化的Ts

    • std::variant 永远不会动态分配内存。但是,作为对C ++对象的复杂规则的让步,如果赋值/放置抛出,则variant 可能进入" valueless_by_exception"州。在此状态下,无法访问variant,也无法访问特定成员的任何其他功能。

      如果分配/安置投掷,您只能进入此状态。

  • Boost.Variant包含recursive_variantallows a variant to contain itself。它们基本上是指向boost::variant指针的特殊包装器,但它们与访问机器相关联。

    std::variant没有这样的帮助类型。

  • std::variant提供了更多使用post-C ++ 11功能的功能。例如:

答案 1 :(得分:3)

似乎关于变体类设计的争论的主要观点是,当变量的赋值应该在完成时会破坏旧值时会发生异常:

variant<std::string, MyClassWithThrowingDefaultCtor> v = "ABC";
v = MyClassWithThrowingDefaultCtor();

选项似乎是:

  • 通过将可能的可表示类型限制为nothrow-move-constructible类型来防止这种情况。
  • 保留旧值 - 但这需要双缓冲区(boost::variant显然是这样做。)
  • 拥有一个'脱离'状态,每个变种没有任何价值,并在此类失败时进入该状态。
  • 未定义的行为
  • 在发生类似事件之后尝试读取其值时使变量抛出

如果我没弄错的话,后者就是被接受了。

这是由Axel Naumann于2015年11月从ISO C ++博客post总结的。

答案 2 :(得分:0)

std::variant 与 boost::variant 略有不同

  • std::variant 在头文件中声明,而不是在
  • std::variant 从不分配内存
  • std::variant 可与 constexpr 一起使用
  • 您必须为 std::variant 编写 std::get_if(&variable) 而不是编写 boost::get(&variable)
  • std::variant 不能递归地保持自身并遗漏了一些其他高级技术
  • std::variant 可以就地构造对象
  • std::variant 有 index() 而不是 which()