C ++ 17呈现std::variant
和std::any
,它们都能够在对象下存储不同类型的值。对我来说,它们在某种程度上是相似的(是吗?)。
此外,std::variant
限制条目类型。为什么我们更喜欢使用std::variant
而不是std::any
?
答案 0 :(得分:12)
在编译时检查的内容越多,运行时的错误也越少。
variant
保证它包含一种类型列表(加上无值的异常)。它为您提供了一种保证在其上运行的代码考虑带有std::visit
的变体中的每种情况的方法;即使是variant
(或更多)的对的所有情况。
any
否。使用any
时,您可以做的最好的事情是“如果类型不完全符合我的要求,则某些代码将无法运行”。
variant
存在于自动存储中。 any
可以使用免费商店;这意味着any
具有性能,而noexcept(false)
则具有variant
没有的性能。
对于any
,检查其中N种类型为O(N);对于variant
,为O(1)。
any
是打扮void*
。 variant
是打扮union
的人。
any
无法存储不可复制或不可移动的类型。 variant
可以。
variant
的类型是代码阅读者的文档。
通过API传递variant<Msg1, Msg2, Msg3>
使操作显而易见;在此处传递any
意味着理解API需要可靠的文档或阅读实现源。
任何对静态无类型语言感到沮丧的人都将了解any
的危险。
现在,这并不意味着any
不好;它只是不能解决与variant
相同的问题。作为用于类型擦除目的的可复制对象,它可能很棒。运行时动态类型具有它的位置;但是那个地方不是“无处不在”,而是“无法避免的地方”。
答案 1 :(得分:4)
区别在于对象存储在 devServer: {
contentBase: path.join(__dirname, './application/dist'),
compress: true,
port: 9000
}
分配的内存中:
cppreference.com - std::variant
与联合一样,如果变量包含某个对象类型
std::variant
的值,则T
的对象表示形式将直接分配在变量本身的对象表示形式内。不允许变体分配额外的(动态)内存。
并且对于T
,这是不可能的。
从std::any
开始,std::variant
本身只需要分配一次内存,并且可以保留在堆栈中。
答案 2 :(得分:2)
除了从不使用其他堆内存之外,variant
还有一个优点:
您可以std::visit
到variant
,但不能any
。