Is my book discussion about lambda return types wrong?

My book says:

Lambdas with function bodies that contain anything but one return statement that does not indicate the return type return return.

but this:

auto f = []{ int i=0; i++; return std::string("foo"); }; std::cout << f() << std::endl; 

actually compiles and outputs "foo", but this lambda expr has more than just one return statement, so it should return void because it does not manually specify "-> std :: string" as the return type.

What's going on here?

I use the Apple compiler in the latest Xcode 4.6, based on Clang 3.2, it seems:

clang --version

Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) Target: x86_64-apple-darwin12.2.0 Theme model: posix

+13
c ++ lambda c ++ 11 clang llvm
Feb 06 '13 at 20:38
source share
5 answers

The book accurately reflects the rules in the draft n3290 Standard. Your compiler may have implemented another project.

In section 5.1.2p4, the project reads

If the lambda expression does not include the return type of the return type, it is as if the type trailing-return-type denotes the following type:

  • if the compound statement is of the form { expression-specifier-seq opt return expression ; } type of the returned expression after lvalue-to-rval conversion, matrix to pointer conversion, and function to pointer conversion;
  • otherwise void.

The syntax of attribute-specifier-seq can be alignas or double-bound attributes. Invariable declarations.

Project n3485, which, after publishing C ++ 11 (i.e., works in the direction of C ++ 1y), contains the same wording. I do not know if there was another rule in some project earlier than n3290.

+6
Feb 06 '13 at 20:43
source share

If you use popular compilers (gcc, Visual Studio), you usually do not need to specify the type of the return value, if the compiler can determine it unambiguously - as in your example.

The following example shows lambda, which requires explicit return type information:

 auto lambda = [](bool b) -> float { if (b) return 5.0f; else return 6.0; }; 

I asked Bjarn Straustrup about this, his comment:

I do not know if C++11 allows the deduction of the return type is there are several return statements with identical return type. If not, that's planned for C++14.

+3
Feb 06 '13 at 20:41
source share

I'm not sure what to do from the quote in the question, but here is what the C ++ 11 standard says about lambdas without a declarator or return type:

If the lambda expression does not contain a lambda declarator, it is equal if the lambda declarator was (). If the lambda expression does not include the trailing-return-type type, it looks like the return type of the return type indicates the following type (5.1.2p4):

- if the compound operator is of the form {expression-specifier-seqopt return expression; } type the return expression after converting lvalue-to-rvalue (4.1), converting the array to a pointer (4.2) and converting a function to a pointer (4.3);

- otherwise void.

+1
Feb 06 '13 at 20:46
source share

Clang implements the proposed C ++ core issue 975 solution. This allows an arbitrary body for a lambda with any number of return statements, and deduces the return value from the returned expression, provided that they must all produce the same type.

In C ++ 14, this support is further summarized by N3638 , which was voted in favor of a working draft standard for the Bristol meeting of WG21.

+1
May 6 '13 at 6:39
source share

The draft n3485 indicates that if the compiler can uniquely determine the type of return value, this will allow the lambda not to specify it.

0
Feb 06 '13 at 20:44
source share



All Articles