C ++ 17呈现std::variant和std::any,都能够在对象下存储不同类型的值。对我来说,它们在某种程度上是相似的(是吗?)。
除此以外,还std::variant限制了条目类型。为什么我们应该更喜欢std::variant在std::any这简单的使用?
Yak*_*ont 14
编译时检查的内容越多,运行时错误的数量就越少。
variant保证它包含类型列表之一(加上无值的异常)。它为您提供了一种方法,以确保在其上运行的代码考虑带有std::visit; 的变体中的每种情况。甚至每对都为variants(或更多)。
any才不是。随着any你能做的最好的是“如果类型不完全是我要求的,一些代码将无法运行”。
variant存在于自动存储中。 any可以使用免费商店;这种方法any具有的性能和noexcept(false)该问题variant没有。
检查-中的N个类型中的哪一个是O(N),any因为variant它是O(1)。
any是一个打扮void*。 variant是一个打扮union。
any无法存储不可复制或不可移动的类型。 variant能够。
类型variant是供您的代码读者阅读的文档。
传递variant<Msg1, Msg2, Msg3>通过API使操作明显; 通过any那里意味着了解API需要可靠的文档或阅读实现源。
任何对静态无类型语言感到沮丧的人都将理解的危险any。
现在,这并不意味着any不好;它不能解决与相同的问题variant。作为用于类型擦除目的的可复制对象,它可能很棒。运行时动态类型具有它的位置;但是那个地方不是“无处不在”,而是“无法避免的地方”。
不同之处在于对象存储在由std::variant以下分配的内存中:
cppreference.com - std::variant
与联合一样,如果一个变体持有某个对象类型的值
T, 则 的对象表示T直接在变体本身的对象表示中分配。不允许 Variant 分配额外的(动态)内存。
并且std::any这是不可能的。
至于 a std::variant, 只需要为它std::variant自己分配一个内存,它可以留在堆栈上。