gpt4 book ai didi

c++ - std::visit无法识别类型

转载 作者:行者123 更新时间:2023-12-02 09:55:40 32 4
gpt4 key购买 nike

我很困惑,在经过一些代码重构之后,下面的代码不再起作用,因为其中的代码跳转到auto, auto的情况,而忽略了Complex, Complex的情况。我承认我不太了解overload到底在做什么,但是对我来说,这两个代码看起来完全一样,唯一的区别是一个直接获取其参数,而另一个具有在函数主体本身中定义的参数。

Math_Node Function_Manager::add(const Math_Node& arg){
Math_Object obj1 = arg.children_ptr()->at(0)->data();
Math_Object obj2 = arg.children_ptr()->at(1)->data();
if( std::holds_alternative<Complex>(obj1) ){
std::cerr << "obj1 is complex\n";
}
if( std::holds_alternative<Complex>(obj2) ){
std::cerr << "obj2 is complex\n";
}
return std::visit(overload{
[](const Complex& a, const Complex& b) -> Math_Object{
std::cerr << "COMPLEX ADD_\n";
return add_(a, b);
}
, [](const Matrix& a, const Matrix& b) -> Math_Object{
std::cerr << "MATRIX ADD_\n";
return add_(a, b);
}
, [&arg](auto& a, auto& b) -> Math_Node{
std::cerr << "NOT FOUND\n";
return arg;
}
}, obj1, obj2);
}

代码打印
obj1 is complex
obj2 is complex
NOT FOUND

这是重构之前的工作代码:
Math_Object Function_Manager::add(const Math_Object& arg0, const Math_Object& arg1){
return
std::visit(
overload{
[](const Complex& a, const Complex& b) -> Math_Object{ return add_(a, b); }
, [](const Matrix& a, const Matrix& b) -> Math_Object{ return add_(a, b); }
, [](auto& a, auto& b) -> Math_Object{
throw std::runtime_error(
("Unsupported arguments for add: " + to_string(a) + to_string(b)).c_str());
}
}, arg0, arg1
);
}

我唯一能想到的是 obj1obj2并不是真正想要的类型,但是打印到 std::cerr可以证明它们是正确的。那么,为什么std::visit无法如此识别它,而 我该如何解决?

最佳答案

在您的第一个示例中,obj1obj2不符合const

在第二个示例中,arg0arg1是。
overload只是对分配给它的所有lambda的调用运算符进行重载解析(假定它是通常的实现)。

在第一个示例的重载解析中,auto& / auto&obj1 / obj2const Complex& / const Complex&更好地匹配,因为后者需要进行资格转换以添加const,而auto& / auto&可以推导为Complex& / Complex&,而不能推导为需要资格转换。

在第二个示例中不是这种情况,因为arg0 / arg1const,所以auto& / auto&的模板参数推导将产生const Complex& / const Complex&,并且此调用以及直接采用const Complex& / const Complex&的调用都不需要任何转换。

如果两个函数的调用转换顺序相同,则该调用将通过一些其他标准来消除歧义,其中之一是非模板函数优于模板函数。直接使用const Complex& / const Complex&的重载不是模板(因为它不是通用lambda),因此是首选。

要解决此问题,只需在所有调用中使用相同的资格,即在上次调用中使用const auto& / const auto&代替auto& / auto&,或者通过将std::as_const(obj1)std::as_const(obj2)而不是obj1obj2传递给std::visit来重现第二个示例的重载解决方案行为。

关于c++ - std::visit无法识别类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60325601/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com