sergiol
sergiol

Reputation: 4337

Lambda did not automatically deduce return type

When I answewred my own question on https://stackoverflow.com/a/32115498/383779 , I got another doubt.

In

const CArray<CItem*>& Items=
    (ItemsInput!= nullptr)?
        *ItemsInput
    :
        [this]() -> const CArray<CItem*>&
        {
            CArray<CItem*> InnerItems;
            GetContainer().GetInnerItems(InnerItems, NULL, true);
            return (InnerItems);
        } ()
;

I tried to remove the -> const CArray<CItem*>& return part, but it gave two errors when compiling:

1>FunctionClass.cpp(line of last semicolon): error C2440: 'initializing' : cannot convert from 'void' to 'const CArray<TYPE> &'
1>          with
1>          [
1>              TYPE=CItem *
1>          ]
1>          Expressions of type void cannot be converted to other types


1>FunctionClass.cpp(line of the return statement): error C3499: a lambda that has been specified to have a void return type cannot return a value

Can somebody explain why? Wasn't is supposed for the lambda to automatically deduce the type to be returned from its return statement?

Upvotes: 3

Views: 722

Answers (2)

ForEveR
ForEveR

Reputation: 55887

From C++11 standard (N3242 5.1.2/4 it's really old specification)

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-seq opt return 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.

since your lambda is not just return expression, return-type is void.

This is considered a defect in C++11 (DR-985) and many compilers have relaxed those restrictions to the C++14 even in C++11 mode (thanks @dyp).

Upvotes: 6

Johan Lundberg
Johan Lundberg

Reputation: 27038

You need to compile with C++14 support for that to work in cases where the body is more than just a return statement. What compiler and version are you using?

In any case, why do you return (InnerItems) instead of InnerItems ? Is it to explicitly return a reference to that local variable?

Upvotes: 1

Related Questions