[英]When should I use std::any
由于引入了 C++17 std::any
。 现在可以编写这样的代码
#include <iostream>
#include <any>
#include <string>
int main () {
const double d = 1.2;
std::any var = d;
const std::string str = "Hello World";
var = str;
}
一个 double 被分配给变量var
而不是一个std::string
被分配给它。
为什么引入std::any
?
我认为这违反了least astonishment rule
,因为我发现很难想到一种情况,可以用它来更清楚地表达我喜欢表达的东西。
有人可以举一个很好的例子,当std::any
是有益的。
何时使用
void*
作为具有一些有限用例的极其不安全的模式, std::any
增加了类型安全性,这就是为什么它有一些实际用例。
一些可能性:
我将其总结为经典的“当你无法避免时使用它”。
我只能想到动态类型脚本语言的非性能关键实现来表示来自脚本世界的变量,但即使如此( Boost.Spirit/example/qi/compiler_tutorial没有这样做,对于解析器和运行)。
对于从解析器(例如Boost.Spirit.X3 )到库 API(例如ASIO )的所有其他内容,通常会有更快/更好/更具体的替代方案,因为很少有东西是真正的“任何东西”,大多数都比这更具体.
std::variant
和/或std::optional
用于“几乎任何值”std::packaged_task
/ std::function
+ lambdas 用于“带参数的回调”,这将是 C API 中void*
的情况。 std::any
是一种词汇类型。 当您需要存储一些东西时,您可以使用它作为值。
它有许多“第一级”用途:
当与本身具有此类类型的脚本语言进行交互时,这是一种自然的搭配。
当您拥有一棵具有高度多态内容的属性树,并且树的结构与树的生产者和消费者解耦时。
当替换通过中间层的void*
数据块时,中间层实际上并不关心它携带的是什么。
在其他情况下,它也可以用作构建块。 例如, std::function
可以选择将其值存储在std::any
:
template<class R, class...Args>
struct func<R(Args...)> {
mutable std::any state;
R(*f)(std::any& state, Args&&...) = nullptr;
template<class T>
void bind(T&& t) {
state = std::forward<T>(t);
f = [](std::any& state, Args&&...args)->R {
return std::any_cast<T&>(state)(std::forward<Args>(args)...);
};
}
R operator()(Args...args)const {
return f(state, std::forward<Args>(args)...);
}
};
这是(大部分) std::function
一个非常小的实现。 基本上我已经使用any
来键入擦除复制/移动/销毁。
您可以在其他地方使用它来解决类似的问题(您正在对某些操作进行类型擦除,并且还想输入擦除复制/移动/销毁),或者对其进行概括。
它在 Wt 中使用,为表格数据提供非模板接口。
内置和 Wt 类型有到字符串的转换,您可以通过专门化Wt::any_traits
来注册额外的转换。 这允许将任何内容显示为表中的条目,视图类不必知道有关它们显示的类型的任何信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.