【问题标题】:lambda returning boollambda 返回布尔值
【发布时间】:2011-12-14 21:39:12
【问题描述】:

我想找到 Y 坐标较小的点(如果这样的点更多,找到 X 最小的点)。 使用 lambda 编写时:

    std::min_element(begin, end, [](PointAndAngle& p1, PointAndAngle& p2) {
        if (p1.first->y() < p2.first->y())
            return true;
        else if (p1.first->y() > p2.first->y())
            return false;
        else 
            return p1.first->x() < p2.first->x();
    }

我得到:

error C3499: a lambda that has been specified to have a void return type cannot return a value

有什么区别:

    // works
    std::min_element(begin, end, [](PointAndAngle& p1, PointAndAngle& p2) {
        return p1.first->y() < p2.first->y();
    }

    // does not work
    std::min_element(begin, end, [](PointAndAngle& p1, PointAndAngle& p2) {
        if (p1.first->y() < p2.first->y())
            return true;
        else 
            return false;
    }

【问题讨论】:

  • if(expression) return true; else return false; 的构造本质上是丑陋的。如果表达式真的是布尔值,则丑陋的两倍。
  • @MichaelKrelin-hacker:是的,但这不是编译器拒绝最后一个示例的原因。
  • MSalters,当然,这就是为什么评论而不是回答。这就是“有什么区别”这个问题的答案。这是主要区别;)

标签: c++ visual-studio-2010 lambda


【解决方案1】:

正如 Mike 所指出的,如果 lambda 的主体是单个 return 语句,则从该语句推断返回类型(参见 5.1.2/4)(感谢 Mike)。

std::min_element(begin, end, [] (const PointAndAngle & p1, const PointAndAngle & p2)
  -> bool 
 {
    if (p1.first->y() < p2.first->y())
         return true;
    else 
        return false;
}

注意-&gt; bool

【讨论】:

  • 通过 const-reference 获取参数可能也很好,因为算法很可能想给你那个。
  • 谢谢! -&gt; bool 不应该在 () 之后而不是 [] 之后?
  • 我猜是因为在简单的一行形式中,cmpiler 可以很容易地推断出返回类型,而一旦你引入条件,他可能无法做到这一点。尽管您是对的,但明确返回类型总是一个好主意。
  • 这里有两个错误:bool 放错地方了,正如relaxxx 所说;第二行有return 而不是if
  • @TonyK:感谢您的提示。我现在不知道我是如何复制/匆忙的:)
【解决方案2】:

可以隐式推断 lambda 的返回类型,但您需要有一个 return 语句来实现这一点;这就是你的“工作” lambda 工作的原因(返回类型推断为 bool)。

sehe 的解决方案明确声明了返回类型,因此它也可以正常工作。

更新:

C++11 标准,§5.1.2/4 规定:

如果 lambda 表达式不包含 trailing-return-type,它是 好像尾随返回类型表示以下类型:

  • 如果复合语句的形式为 { return expression ; } 后面的返回表达式的类型 左值到右值的转换(4.1),数组到指针的转换 (4.2),以及函数到指针的转换(4.3);

  • 否则,void

您不工作的 lambda 属于第二类。

【讨论】:

  • 有趣的是,维基百科还包括 如果返回表达式通过 decltype 传递时所有返回值的位置都返回相同的类型。 可以省略的 lambdas 集合返回类型。但看起来,根据标准,情况并非如此。
  • @mackenir:实际上在深入研究标准之前,我认为这也可能是编译器的限制(最初的答案是这样写的,但是在发布后很快就进行了编辑,所以没有得到记录)。维基百科在技术上肯定是不正确的。
  • 顺便说一句,您是否购买了 C++11 标准的副本?我找不到免费下载。
  • @mackenir:您可以从here 下载 N3242。这不是官方标准(只是 2 月份的工作副本),但差异应该很小。
猜你喜欢
  • 2013-08-18
  • 1970-01-01
  • 2020-07-29
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多