Reputation: 10480
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
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 fromreturn
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 eachreturn
statement. If the type deduced is not the same in each deduction, the program is ill-formed.
Upvotes: 14
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