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;
};
The return type for a lambda is specified using a C++ feature named 'trailing return type'. This specification is optional. Without the trailing return type, the return type of the underlying function is effectively 'auto', and it is deduced from the type of the expressions in the body's return statements.
Lambdas can both capture variables and accept input parameters. A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. auto y = [] (int first, int second) { return first + second; };
Can you create a C++11 thread with a lambda closure that takes a bunch of arguments? Yes – just like the previous case, you can pass the arguments needed by the lambda closure to the thread constructor.
Return Value A C++ lambda function executes a single expression in C++. A value may or may not be returned by this expression. It also returns function objects using a lambda.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With