std :: variant vs std :: any当type是move constructible时

时间:2017-09-05 10:47:38

标签: c++ performance types c++17

如果我的类型为std::is_nothrow_move_constructible,我需要将其存储在std::anystd::variant中,您建议使用哪一个?为什么?哪一个会产生最少的开销?修改:std::variantstd::any的不同用例有哪些?

class MyType
{
public:
   MyType(const MyType&) = default;
   MyType(MyType&&) = default;
   MyType() = default;
};

int main(int argc, char* argv[])
{
   static_assert(std::is_nothrow_move_constructible<MyType>::value, "Not move constructible");
   return 0;
}

3 个答案:

答案 0 :(得分:8)

如果您知道类型,请使用std::variant。在这种情况下,您知道所有可能的类型,并使用std::variant::visit()将访问者应用于变体。

如果不这样做,请使用std::any。在处理通用类型时,您可以考虑这一点。换句话说,当这些类型不为先知时。

  

哪一个会产生最少的开销?

std::variant,无法使用堆。这是不允许的。如果没有动态分配,就没有办法实际拥有包含自身可能变体的结构,因为如果静态声明,这样的结构可以很容易地显示为无限大小。 Source

相反,std::any可能会这样做。因此,第一个将具有更快的构造和复制操作。

答案 1 :(得分:2)

std::any为堆中的值分配存储空间。而std::variant不使用堆,因此它在构造和复制方面更有效,并且更加缓存友好,因为值直接存储在对象中,并且它不涉及间接和虚函数来访问它。

std::variant的界面更丰富,更易于使用。

std::any仅在由于某种原因无法使用std::variant时才有用。

答案 2 :(得分:1)

出于类型安全,松耦合和易于维护的原因:

如果可能的话,

更喜欢variant而不是any

因为从本质上讲,std::any是围绕可克隆std::unique_ptr<void, some_deleter>的糖衣。

对于糟糕的演员阵容有一些保护(它会抛出而不是崩溃,在许多程序中它们都是相同的东西)。