自从std::any
引入C++ 17以来.现在可以编写这样的代码了
#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;
}
Run Code Online (Sandbox Code Playgroud)
双被分配给变量var
和比std::string
被分配给它.
为什么要std::any
介绍?
我认为这违反了least astonishment rule
,因为我发现很难想到一种情况,这可以用来表达更清楚,我想表达的内容.
有人能给我一个很好的例子吗std::any
?
May*_*yur 10
什么时候使用
void*
作为一个非常不安全的模式与一些有限的用例,std::any
添加类型安全性,这就是为什么它有一些真实的用例.
一些可能性:
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)...);
}
};
Run Code Online (Sandbox Code Playgroud)
这是(大部分)的一个相当小的实现std::function
。基本上我习惯于any
输入擦除复制/移动/销毁。
您可以在其他地方使用它来解决类似的问题(您正在键入擦除某些操作并且还想键入擦除复制/移动/销毁),或将其概括。
我将其总结为经典的“在无法避免时使用”。
我只能想到动态类型脚本语言的非性能关键实现来表示来自脚本世界的变量,但即使如此(Boost.Spirit/example/qi/compiler_tutorial没有这样做,对于解析器和运行)。
对于从解析器(例如Boost.Spirit.X3)到库 API(例如ASIO)的其他所有内容,通常会有更快/更好/更具体的替代方案,因为很少有东西是真正的“任何东西”,大多数都比这更具体.
std::variant
和/或std::optional
“几乎任何价值”std::packaged_task
/ std::function
+ 用于“带参数回调”的 lambda,这将是void*
C API 中的一种情况。具体来说,我不会盲目地将它作为 a 的替代品void*
,因为它可能会在堆上分配内存,这对于高性能代码来说可能是致命的。