C++:检查存储在std::any中的值是否为整数

有一个值存储在std::any,我想知道它是整数值(char, short, int, long,有符号和无符号)还是浮点值(float, double),或其他东西。

如果我只需要检查int值,我会这样做:

std::any a;
if (a.type() == typeid(int)) {
  // do some logic for int
}

但是if (a.type() == typeid(int) || a.type() == typeid(signed char)...)在 C++ 中为所有整数类型做一个巨人似乎......很糟糕。

如果我可以以某种方式访问该类型,我可以使用is_arithmetic<T>from但我没有,我只有which 返回。type_traitsTstd::any#type()std::type_info

有没有办法在if条件中没有很多很多分离的情况下实现这一点?

(如果重要的话,我使用 C++20)

回答

std::any 是一个类型擦除类。

它只记住确切的类型,以及转换回该确切类型的能力(以及如何复制/移动/销毁它)。

如果您想记住有关存储类型的其他事实,您必须自己完成这项工作。

有没有办法在得到Tstd::any没有确切的检查是T

通常,使用std::any无法控制的将“任何东西”推入其中会导致混乱。 std::any允许您使用一组“开放”类型来执行此操作,因此您可以安全地将数据从一个代码点传递到另一个代码点,而中间代码不需要知道它是什么。

它不能让您使用未知类型生成类型感知代码。


为了解决您的问题,有多种解决方案。

  1. 如果您支持的类型集已关闭(以某种方式修复),请使用std::variant.

  2. 如果类型集大部分是封闭的,请使用std::variant< bunch, of, types, std::any >. 然后,您可以将“大部分封闭”类型作为variant. std::any如果类型输入可以转换为任何其他类型,则使用阻止转换的代码可能是明智的。

  3. 如果您愿意编写自己的类型擦除,则可以编写自己的类型擦除或std::any添加额外信息。

  4. 您可以编写一个实用函数来执行大量 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++ 语言反转。

  • a query into a set of `std::type_index`es of allowed int types might be an option

以上是C++:检查存储在std::any中的值是否为整数的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>