C++17 提出了 std::variant
和 std::any
,它们都能够在一个对象下存储不同类型的值。对我来说,它们在某种程度上相似(是吗?)。
此外 std::variant
限制条目类型,除此之外。为什么我们应该更喜欢 std::variant
而不是 std::any
更易于使用?
原文由 masoud 发布,翻译遵循 CC BY-SA 4.0 许可协议
C++17 提出了 std::variant
和 std::any
,它们都能够在一个对象下存储不同类型的值。对我来说,它们在某种程度上相似(是吗?)。
此外 std::variant
限制条目类型,除此之外。为什么我们应该更喜欢 std::variant
而不是 std::any
更易于使用?
原文由 masoud 发布,翻译遵循 CC BY-SA 4.0 许可协议
不同之处在于对象存储在 std::variant
分配的内存中:
cppreference.com - std::variant
与联合一样,如果一个变体包含某个对象类型的值
T
,则 ---T
对象表示直接在变体本身的对象表示中分配。不允许变体分配额外的(动态)内存。
对于 std::any
这是不可能的。
到目前为止, std::variant
只需要为 std::variant
本身分配一个内存,并且它可以保留在堆栈上。
原文由 t.niese 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
你在编译时检查的东西越多,你的运行时错误就越少。
variant
保证它包含一个类型列表(加上异常无价值)。它为您提供了一种方法来保证在其上运行的代码会考虑变体中的每种情况std::visit
;即使是 一对variant
s(或更多)的每个案例。any
没有。使用any
你能做的最好的事情是“如果类型不完全符合我的要求,一些代码将无法运行”。variant
存在于自动存储中。any
可以使用免费商店;这意味着any
具有性能,而noexcept(false)
问题variant
没有。对于 --- 检查 N 个类型中的哪一个是 O(N)
any
对于variant
它是 O(1)。any
是装扮的void*
。variant
是装扮的union
。any
不能存储不可复制或不可移动的类型。variant
可以。variant
的类型是代码读者的文档。通过 API 传递
variant<Msg1, Msg2, Msg3>
使操作显而易见;通过any
这意味着理解 API 需要可靠的文档或阅读实现源。任何对静态无类型语言感到沮丧的人都会理解
any
的危险。现在这并不意味着
any
不好;它只是不能解决与variant
相同的问题。作为用于类型擦除目的的可复制对象,它可能很棒。运行时动态类型有它的位置;但那个地方不是“无处不在”,而是“你无法避免的地方”。