我有一个整数数组来检索std::variant中的内容。但是它编译失败,错误消息No matching function to call 'get'
。你能解释一下为什么,并建议工作解决方案来达到同样的目的吗?
using my_type = std::variant<int, float, bool>;
constexpr int[] expected_types = {2,2,2,2};
bool validate(std::vector<my_type> input) {
bool rst;
if (input.size() != 4) {
return false;
}
for (int i = 0; i < 4; i++) {
rst = rst || std::get<my_type[i]>(input[i]);
}
return rst;
}
下面是更多的上下文。类A、B、C都实现了接口bool foo(std::vector<my_type> input)
。但是类A的输入是{int,int,bool}格式,类B的输入是{int,int,float}格式,类C的输入是{bool,bool}格式。每个类中的expected_types将自己的类型保存在输入向量中。然后std::get〈expected_types[i]〉用于访问输入向量中的元素。您能建议一个清晰优雅的模式来适合我的情况吗?
非常感谢!
6条答案
按热度按时间lb3vh1jj1#
如果我正确理解了
validate
函数,它应该验证vector<variant<int, float, bool>>
...1.具有
A
、B
或C
类型的正确长度。1.包含由
A::expected_types[]
、B::expected_types[]
或C::expected_types[]
中的variant
索引指示的variant
类型。然后,它可以将正在测试
vector
的类型(A
、B
或C
)作为模板参数,并使用variant::index()
来检查各个variant
在vector
中持有的类型。将它与
&&
上的一个fold(因为你希望所有的都是true
)结合起来,你会得到:如果您“真的”想从
vector
中std::get
expected_types
,并使用逻辑OR
,可以通过类似的方式完成,但要在||
上折叠:Demo
k5hmc34c2#
因为函数get需要类型或编译时常量作为索引,所以您的方法将不起作用。
为了达到你想要的,你需要修改你的函数,使它成为一个函数模板。
然后,在调用“validate”函数时,可以将bool的索引值作为编译时常量模板参数提交。
你的程序看起来就像这样:
如果以后需要扩展validate函数来处理其他类型的
std::variant
,可以使用可变参数模板和constexpr if
来实现请反馈,如果这是解决方案是足够的你.
7xllpg7q3#
使用
std::variant::index
可以很好地实现目标:https://godbolt.org/z/G9aMfWfEn
alen0pnh4#
my_type
不是一个数组,所以my_type[i]
没有意义。我猜
std::get<my_type[i]>(input[i])
应该是std::get<expected_types[i]>(input[i])
?这也不起作用,因为i
不是编译时常量,所以不能用作模板表达式。一种解决方法是展开
for
循环:如果你实际上要做的是检查类型是否与预期的类型匹配,那么你可以使用
index
方法:5kgi1eie5#
您只能通过指定类型或索引来访问变量,如:
但是,如果您不显式指定类型或索引,就可以使用访问器来处理从循环中的向量访问变量的问题(我们甚至不需要另一个变量来保存向量中变量类型的索引)
访问者结构可用于对变量的值执行逻辑或操作,并保存稍后返回的结果。
vwoqyblh6#
正如我提到的,这种验证是一件痛苦的事情,需要大量的赘言,包括专门化。
这使用了C++17语法,我认为这在2023年是合理的,这也验证了向量中的每个变量实际上都是正确的类型,如果不是,则验证失败,这在问题中没有明确说明,但我相当确定这是隐含的。