Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
250 views
in Technique[技术] by (71.8m points)

c++ - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...