template boy
template boy

Reputation: 10480

C++11 restrictions on lambda return type

I'm reading here on cppreference about how a return type of a C++11 lambda is deduced:

if the body consists of the single return statement, the return type is the type of the returned expression (after rvalue-to-lvalue, array-to-pointer, or function-to-pointer implicit conversion)

So I think that means that a lambda can only have one return statement. But why does it work with multiple return statements still?

This compiles on both compilers:

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

Upvotes: 11

Views: 3235

Answers (2)

Columbo
Columbo

Reputation: 60969

That is slightly imprecise. [expr.prim.lambda]/4:

If a lambda-expression does not include a lambda-declarator, it is as if the lambda-declarator were (). If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type:

  • if the compound-statement is of the form

    { attribute-specifier-seqoptreturn expression ; }

    the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);

  • otherwise, void.

So the return type is only deduced if the whole body of the lambda expression only consists of one sole return statement.

Both GCC and Clang are not standard conforming in this case as they issue an error message if and only if two return statements lead to inconsistent deductions. This is because they already implemented the C++14 standard which deducts the return type even with multiple return statements and/or multiple other statements present. [expr.prim.lambda]/4 specifies that

The lambda return type is auto, which is replaced by the trailing-return-type if provided and/or deduced from return statements as described in 7.1.6.4.

§7.1.6.4/9

If a function with a declared return type that contains a placeholder type has multiple return statements, the return type is deduced for each return statement. If the type deduced is not the same in each deduction, the program is ill-formed.

Upvotes: 14

Steve Vinoski
Steve Vinoski

Reputation: 20004

It works with your example because all the return statements return values of the same type. But try changing the second return to a different type, for example:

auto f = [] (bool c1, bool c2) {
    if (c1) return 1;
    if (c2) return "";
    else    return 3;
};

Compiling this with clang++ yields the following error:

main.cpp:3:13: error: return type 'const char *' must match previous return type 'int' when lambda expression has unspecified explicit
      return type
    if (c2) return "";
        ^
1 error generated.

Upvotes: 3

Related Questions