std::any
是一个类型擦除类。
它只记住确切的类型,以及转换回该确切类型的能力(以及如何复制/移动/销毁它)。
如果您想记住有关存储类型的其他事实,您必须自己完成这项工作。
如果不检查确切的内容,就无法进入T
内部。std::any
T
一般来说,在std::any
没有控制的情况下将“任何东西”推入其中会导致一团糟。 std::any
允许您使用一组“开放”类型来执行此操作,因此您可以安全地将数据从一个代码点传递到另一个代码点,而中间代码不需要知道它是什么。
它不能让您使用未知类型生成类型感知代码。
为了解决您的问题,有多种解决方案。
如果您支持的一组类型已关闭(以某种方式修复),请使用std::variant
.
如果类型集大部分是封闭的,请使用std::variant< bunch, of, types, std::any >
. 然后,您可以将“大部分关闭”的类型处理为variant
. std::any
如果类型输入可以转换为任何其他类型,则使用阻止转换为的代码可能是明智的。
如果您愿意编写自己的类型擦除,您可以编写自己的或增加std::any
额外的信息。
您可以编写一个实用函数来执行大量 if 语句,可能使用模板,在时间上与类型数量成线性关系。
对于 1/2,
auto is_integral_f = [](auto&& x){ return std::is_integral<std::decay_t<decltype(x)>>{}; };
std::variant<int,char,unsigned int, long, double, std::any> bob;
bob = 3;
assert( std::visit( is_integral_f, bob ) );
对于 3,这里是一个引擎的示例,它使类型擦除更简单一些;自己写是可以的。然后我们简单地:
auto is_integral = any_method<bool()>{ is_integral_f };
super_any<decltype(is_integral)> my_any;
my_any bob = 3;
my_any alice = 3.14;
assert( (bob->*is_integral)() );
assert( !(alice->*is_integral)() );
对于 4,
template<class...Ts>
bool is_any_of_types( std::any const& a ) {
return (( a.type() == typeid(Ts) ) || ... );
}
这是线性的sizeof...(Ts)
。
如果散列很大,您可能会喜欢Ts...
它,但我怀疑它会变得足够大。您仍然需要自己枚举类型;is_integral<T>
不能被 C++ 语言反转。