【问题标题】:Lambda expression to return bool in if statement在 if 语句中返回 bool 的 Lambda 表达式
【发布时间】:2019-05-24 08:37:50
【问题描述】:

为了切入正题,我想使用if() 语句中的lambda 表达式返回truefalse。我看到这个问题与我的问题相似:LINK 但我找不到答案。

这是我的示例代码:

if([&rel_pose](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    }) // do smth

当我尝试编译时出现此错误:

 error: could not convert ‘<lambda closure object>graphslam::GraphSLAM::main_pose_callback(const ConstPtr&)::<lambda(Eigen::VectorXd)>{rel_pose}’ from ‘graphslam::GraphSLAM::main_pose_callback(const ConstPtr&)::<lambda(Eigen::VectorXd)>’ to ‘bool’
  })

好的,阅读错误我认为我没有调用该函数,因为编译器不会将表达式视为布尔值。所以我尝试使用这段代码:

if(([&rel_pose](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    };)) // do smth

还有错误:

expected ‘)’ before ‘;’ token
  };)) return;

这可能看起来像一个明显的错误,但对我来说,我可能没有正确理解语法并想问发生了什么。

编辑: 请注意,我已经简化了代码,以便您可以轻松复制错误。我知道这种特殊情况下的 lambda 表达式没有任何意义。

【问题讨论】:

  • 您只是在定义 lambda,而不是调用它。尝试调用该函数。提示:lack of () ;)
  • 在那个地方定义一个 lambda 是没有意义的。在 if 表达式中,您应该直接执行比较表达式,不需要 lambda。您可以定义 lambda 并立即执行它,但这完全是晦涩难懂的编码,
  • 为什么你不只是 return sqrt(pose(0) * pose(0) + pose(1) * pose(1)) &lt; 2; 没有不必要的 ? true : false
  • @aikhs - 您可能希望将该解释编辑到帖子中。否则你肯定会一遍又一遍地被问到这个问题。
  • @Klaus - 三个人很好地理解了 Q。这不是我们检查 OP 的“真实代码”的地方。他们减少了它(虽然可以减少更多),我们回答。

标签: c++ lambda c++14


【解决方案1】:

你忘了调用你的 lambda。现在您说的是 if(function_pointer),因此编译器无法将其转换为布尔表达式。


因此,带有布尔 lambda 的简单 if 子句可以写成:

if ([]() {
    return true;
}()) {
    //do sth
}

在捕获变量的同时将变量作为参数也会出错。你必须做出决定,所以要么:

if([](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    }(rel_pose)){
    //do sth
}

if([&rel_pose]()
    {
        return (sqrt(rel_pose(0) * rel_pose(0) + rel_pose(1) * rel_pose(1)) < 2) ? true : false;
    }()){
    //do sth
}

在这种情况下,对 lambda 的需求是有问题的,您可以去掉 lamdba,将布尔表达式留在 if 子句中。在谈论它时 - 这里不需要使用三元运算符。 return sqrt(rel_pose(0) * rel_pose(0) + rel_pose(1) * rel_pose(1)) &lt; 2; 够用了,更易读。

【讨论】:

  • 比将公式置于条件中更好的是赋予它们语义。 bool condition_name = (...); if( condition_name ){ ... }
【解决方案2】:

这是用捕获短语定义一个 lambda,而不是调用 lambda

[&rel_pose](Eigen::VectorXd pose)
{
  return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
}

如果你想以 rel_pose 作为参数调用 lambda,

[](Eigen::VectorXd pose)
{
  return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
}(rel_pose)

我认为这是正确的

【讨论】:

    【解决方案3】:

    lambda 是一个函数对象。您应该使用() 调用它。

    if ([](Eigen::VectorXd pose)
        {
            return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
        }(rel_pose)) { /* ... */ }
    

    您将rel_pose 作为参数传递而不是捕获它。 无论如何,您可能应该将pose 设为const 参考。

    也就是说,我不知道你想在这里做什么。这样会更好:

    if (sqrt(foo(0) * foo(0) + foo(1) * foo(1)) < 2) { /* ... */ }
    

    【讨论】:

    • 如果您不了解应用程序,您怎么能说一般情况下哪个更好?如果您在帖子中专门谈论示例,则应明确说明。
    • @StoryTeller TBH,我想不出一个直接调用 lambda 的情况会更有意义......
    • 有限的想象力是绝对建议的糟糕基础。
    • @StoryTeller 你能解释一下吗? ;-)
    • 我只是对此有所了解。假设一个人不知道所有目标的谦虚是一种美德。但这是你的答案,也是你的特权。我刚刚说了我的困扰。
    猜你喜欢
    • 2019-09-19
    • 2018-05-27
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    相关资源
    最近更新 更多