避免使用std :: any编写相同的重复类型检查代码 [英] avoid writing the same repetitive type-checking code with std::any

查看:120
本文介绍了避免使用std :: any编写相同的重复类型检查代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在程序中使用std :: any,但是我发现自己在写很多这样的条件语句:

I want to use std::any in my program but I find myself writing a lot of conditional statements like this:

   if (anything.type() == typeid(short)) {
      auto s = std::any_cast<short>(anything);
   } else if (anything.type() == typeid(int)) {
      auto i = std::any_cast<int>(anything);
   } else if (anything.type() == typeid(long)) {
      auto l = std::any_cast<long>(anything);
   } else if (anything.type() == typeid(double)) {
      auto d = std::any_cast<double>(anything);
   } else if (anything.type() == typeid(bool)) {
      auto b = std::any_cast<bool>(anything);
   } 

请注意,为简洁起见,我省略了很多其他内容。

Note that I omitted much of the else if conditions for brevity.

我的程序可以使用可以存储在std :: any中的任何已定义类型,因此这些if-then语句相当长。

My program can use any of the defined types that can be stored in std::any so these if-then statements are quite long. Is there a way to refactor the code so that I can write it once?

我最初的想法是使用这样的模板:

My original inclination was to use templates like so:

template<typename T>
T AnyCastFunction(std::any) {

   T type;
   if (anything.type() == typeid(short)) {
      type = std::any_cast<short>(anything);
   } else if (anything.type() == typeid(int)) {
      type = std::any_cast<int>(anything);
   } else if (anything.type() == typeid(long)) {
      type = std::any_cast<long>(anything);
   } else if (anything.type() == typeid(double)) {
      type = std::any_cast<double>(anything);
   } else if (anything.type() == typeid(bool)) {
      type = std::any_cast<bool>(anything);
   } 

   return type;
}

但是,这导致无法推断出模板参数T错误。我如何重构它以避免在整个程序中多次写大的if / else块?

However, this leads to "couldn't deduce template parameter T" errors. How can I refactor this to avoid writing the large if/else blocks many times throughout the program?

推荐答案

,固定的可能类型列表,请勿使用 std :: any 。使用 std :: variant< Ts ...> 。这使得 Dietmar的答案看起来像这样:

If you have a known, fixed list of possible types, don't use std::any. Use std::variant<Ts...>. That makes Dietmar's answer look like this:

#include <variant>

void test(std::variant<int, double, char const*> v)
{
    std::visit([](auto value){ std::cout << "value=" << value << "\n"; }, v);
}

这是同一件事,除了(a)您不必自己实现 visit (b)这在运行时效率更高,并且(c)这是类型安全的-您不能忘记检查特定类型!确实,即使您不关心(a)或(b),(c)也是巨大的胜利。

which is the same thing, except (a) you don't have to implement visit yourself (b) this is massively more efficient at runtime and (c) this is type safe - you can't forget to check a particular type! Really even if you don't care about (a) or (b), (c) is a huge win.

如果您不关心有一个已知的,可能的类型的固定列表-这是想要 std :: any 的典型用例-然后用<$ c做的任何事情$ c> std :: any 毫无意义。您无法列举所有可能的可复制类型(它们数量不限),因此不一定要检索其内容。所以我真的认为 variant 是您想要的。

And if you don't have a known, fixed list of possible types - which is the typical use-case for wanting std::any - then anything you're doing with std::any doesn't make sense anyway. You can't enumerate all possible copyable types (there are an infinite amount of them), so you can't necessarily retrieve the contents. So I really think variant is what you want.

这篇关于避免使用std :: any编写相同的重复类型检查代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆