Topic: Deduce return type of lambda returning


Author: Tom Honermann <tom@honermann.net>
Date: Tue, 3 Oct 2017 10:22:02 -0400
Raw View
On 10/03/2017 04:45 AM, jeffersoncarpenter2@gmail.com wrote:
> Regarding the return types of lambdas, the c++ standard says in
> section 5.1.2/4
>
> > [...] The lambda return type is auto, which is replaced by the type
> specified by the trailing-return-type if provided and/or deduced from
> return statements [...]
>
> and it provides the examples:
>
> > auto x1 = [](int i) { return i; }; // OK: return type is _int_
>
> > auto x2 = [] { return { 1, 2 }; }; // error: deducing return type
> from _braced-init-list_
>
> However, it is worth noting that the type specifier for both `x1` and
> `x2` is auto.
The type specifiers used to declare 'x1' and 'x2' do not influence the
types associated with the lambda expression; they only declare the types
of 'x1' and 'x2' (and for the code to compile, the type of the lambda
expression must be convertible to those types).  The type of the closure
class and its function call operator are solely determined by the lambda
expression itself (the token sequence starting with '[' and extending to
the closing '}').
>
> If you use a type specifier that defines the return type, e.g.
>
>
> struct Foo { int x; int y; };
>
> function<Foo()> x3 = [] { return { 1, 2 }; };
>
> Foo (*x4)() = [] { return { 1, 2 }; };
>
>
> the definitions of x3 and x4 still produce errors saying that lambdas
> cannot return initializer lists (tested in mingw with -std=c++1z).
> The standard does not allow the return type of a lambda to be
> determined by its type specifier.  Is there any reason this has to be
> this way, or could the standard be updated to allow this in the next
> edition?
Write a trailing return type to explicitly specify the return type for
the function call operator of the closure type.  The section you cited
includes such an example:

int j;
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
//            ^^^^^^^^

To specify your 'Foo' as the return type, do this:

auto x5 = []()->Foo { return { 1, 2 }; };
//            ^^^^^

>
> Why not change the text to say this:
>
> > [...] The lambda return type is auto, which is replaced by the type
> specified by the trailing-return-type if provided, specified by the
> type-specifier if in a definition, and/or deduced from return
> statements [...]
Having the return type be deduced from something outside the lambda
expression would be odd; no other expression in C++ has that kind of
behavior.  How would you define this behavior in cases more complicated
than immediate initialization of (or assignment to?) a variable?  For
example:

function<Foo()> x6 = (1, [] { return { 1,2 }; });

void f(function<Foo()>);
f([] { return { 1,2 }; });  // Deduce based on f's parameter type?

Tom.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/529ed016-ed80-7fd3-e08a-db4f5e4fa018%40honermann.net.

.