避免使用std :: any编写相同的重复类型检查代码 [英] avoid writing the same repetitive type-checking code with 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屋!