【发布时间】:2020-02-20 17:32:12
【问题描述】:
我很困惑,经过一些代码重构后,以下代码不再起作用,因为它跳转到 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
);
}
我唯一能想到的是obj1 和obj2 并不是真正需要的类型,但打印到std::cerr 证明它们是。那么为什么 std::visit 无法识别它,我该如何解决?
【问题讨论】:
-
auto&优先于T const&用于非常量T。尝试将auto&更改为auto const&。 -
然后我得到一个无效的转换错误。
-
@infinitezero 您能否将该错误消息添加到您的问题中?我不明白为什么会有错误。
-
太长了。 Math_Object 是一个包含 Complex 的 std::variant。 Math_Node 是一个模板化节点,其中模板设置为 Math_Object。通过将 lambda 的返回类型更改为 Math_Node 而不是返回 Math_Object(它隐式调用 Math_Node 构造函数),我摆脱了错误消息。
标签: c++ lambda generic-lambda std-variant