对lambda返回类型的C++ 11限制

tem*_*boy 10 c++ lambda return language-lawyer c++11

我在这里阅读关于如何推导出C++ 11 lambda的返回类型的cppreference:

如果正文由单个return语句组成,则返回类型是返回表达式的类型(在rvalue-to-lvalue,array-to-pointer或function-to-pointer隐式转换之后)

所以我认为这意味着lambda只能有一个return语句.但为什么它仍适用于多个return语句?

编译两个编译器:

auto f = [] (bool c1, bool c2) {
    if (c1) return 1;
    if (c2) return 2;
    else    return 3;
};
Run Code Online (Sandbox Code Playgroud)

Col*_*mbo 13

这有点不精确.[expr.prim.lambda]/4:

如果lambda表达式不包含lambda声明符,那就好像lambda声明符一样().如果lambda表达式不包含trailing-return-type,则就好像trailing-return-type表示以下类型:

  • 如果复合语句是形式

    { attribute-specifier-seq optreturn 表达式 ; }

    lvalue-to-rvalue转换(4.1),数组到指针转换(4.2)和函数到指针转换(4.3)之后返回表达式的类型;

  • 否则,void.

因此,仅当lambda表达式的整个主体仅包含一个唯一return语句时,才会推断返回类型.

在这种情况下,GCC和Clang都不符合标准,因为当且仅当两个return语句导致不一致的推论时,它们才会发出错误消息.这是因为他们已经实现了C++ 14标准,即使存在多个return语句和/或多个其他语句,也会扣除返回类型.[expr.prim.lambda]/4指定了

lambda返回类型auto,如果在7.1.6.4中描述的语句中提供和/或推导,则由trailing-return-type替换 .return

§7.1.6.4/ 9

如果具有包含占位符类型的声明返回类型的函数具有多个return语句,则会为每个return语句推导出返回类型.如果推断的类型在每次扣除中不相同,则该程序是不正确的.

  • FWIW,[我问过这个](http://stackoverflow.com/questions/8582610/compiler-warning-lambda-return-type-cannot-be-deduced)几年前:) (2认同)