Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the return type of a lambda expression if an item of a vector is returned?

Consider the following snippet:

#include <iostream> #include <vector> #include <functional>  int main()  {     std::vector<int>v = {0,1,2,3,4,5,6};     std::function<const int&(int)> f = [&v](int i) { return v[i];};      std::function<const int&(int)> g = [&v](int i) -> const int& { return v[i];};      std::cout << f(3) << ' ' << g(3) << std::endl;     return 0; } 

I was expecting the same result: in f, v is passed by const reference, so v[i] should have const int& type.

However, I get the result

 0 3 

If I do not use std::function, everything is fine:

#include <iostream> #include <vector> #include <functional>  int main()  {     std::vector<int>v = {0,1,2,3,4,5,6};     auto f = [&v](int i) { return v[i];};      auto g = [&v](int i) -> const int& { return v[i];};      std::cout << f(3) << ' ' << g(3) << std::endl;     return 0; } 

output:

3 3 

Thus I'm wondering:

  1. In the second snippet, what is the return type of the lambda expression f? Is f the same as g?

  2. In the first snippet, what happened when the std::function f was constructed, causing the error?

like image 802
Jing Li Avatar asked Apr 13 '15 16:04

Jing Li


People also ask

What is the return type of lambda?

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.

What do I return from lambda?

The characteristics of lambda functions are: You can use them as an anonymous function inside other functions. The lambda functions do not need a return statement, they always return a single expression.

What does [=] mean in lambda function?

The [=] you're referring to is part of the capture list for the lambda expression. This tells C++ that the code inside the lambda expression is initialized so that the lambda gets a copy of all the local variables it uses when it's created.

What is the type of lambda function in C++?

The type of a lambda expression is unspecified. But they are generally mere syntactic sugar for functors. A lambda is translated directly into a functor.


1 Answers

The return type of a lambda uses the auto return type deduction rules, which strips the referenceness. (Originally it used a slightly different set of rules based on lvalue-to-rvalue conversion (which also removed the reference), but that was changed by a DR.)

Hence, [&v](int i) { return v[i];}; returns int. As a result, in std::function<const int&(int)> f = [&v](int i) { return v[i];};, calling f() returns a dangling reference. Binding a reference to a temporary extends the lifetime of the temporary, but in this case the binding happened deep inside std::function's machinery, so by the time f() returns, the temporary is gone already.

g(3) is fine because the const int & returned is bound directly to the vector element v[i], so the reference is never dangling.

like image 84
T.C. Avatar answered Sep 20 '22 20:09

T.C.