STD ::变体与STD ::任何当类型移动时可构造时

std::variant vs std::any when type is move constructible

本文关键字:STD 移动 任何当 类型      更新时间:2023-10-16

如果我的类型是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;
}

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

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


哪一个会给最低开销?

std::variant,无法使用堆。不允许。实际上,没有办法拥有一个可能没有动态分配的可能变体的结构,因为如果静态声明,则可以轻松地证明这种结构的大小是无限的。来源。

相比之下,std::any可以这样做。结果,第一个将具有更快的构造和复制操作。

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

如果可以的话,比any更喜欢variant

,因为本质上,std::any在可插的std::unique_ptr<void, some_deleter>周围进行糖衣。

在不良演员周围有一点保护(它会抛出而不是崩溃,在许多程序中相当于同一件事)。

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

std::variant的接口更丰富且易于使用。

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