Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different definitions of the same lambda

I've recently opened this discussion, from which the following problem comes from. This question is a sort of continuous of that discussion. Here is the code:

#include <iostream>
#include <functional>

using namespace std;

std::function<int(void)> mylambda(int starter){
    return [starter]() mutable {
        return ++starter;
    };
}

void tester_wrapper(const std::function<int(void)>& cb, int counter){
    if (counter == 10)
        return;
    else{
        cout << cb() << endl;
        tester_wrapper(cb, counter + 1);
    }
}

void tester(const std::function<int(void)>& cb){
    tester_wrapper(cb, 0);
}

int main()
{
    auto getNum = mylambda(1);

    tester(getNum);
    tester(getNum);
}

In this case the code does what I expected, more specifically it prints all number from 2 to 21. However if my main function was like this:

int main()
{
    auto getNum = ([](int starter) {
        return [starter]() mutable {
            return ++starter;
        };
    })(1);

    tester(getNum);
    tester(getNum);
}

Then the output would be numbers from 2 to 11 repeated twice. I can't explain myself why it produces this output even if the only difference between the 2 pieces of code is where and how the mylambda function is defined.

like image 330
Marco Luzzara Avatar asked Jan 14 '18 09:01

Marco Luzzara


People also ask

What does the name lambda mean?

Lambda, the 11th letter of the Greek alphabet, is the symbol for wavelength. In optical fiber networking, the word lambda is used to refer to an individual optical wavelength.

What is this symbol λ?

Letter. λ • (l) (lowercase, uppercase Λ) The lower case letter lambda (λάμδα), the eleventh letter of the modern Greek alphabet.

What does λ mean in math?

Its namesake, the Greek letter lambda (λ), is used in lambda expressions and lambda terms to denote binding a variable in a function. Lambda calculus may be untyped or typed.

What are the principal differences between the lambda and Def?

The def defined functions do not return anything if not explicitly returned whereas the lambda function does return an object. The def functions must be declared in the namespace.


1 Answers

Because the lambda closure type and std::function are not reference related. Those are separate types. You can't bind a reference to std::function directly to a lambda object.

A lambda object is convertible to a std::function however. So what happens is that the compiler creates a temporary std::function that binds to that const reference. Creating very much the same situation in your original question. Because each call to tester necessitates another temporary object. Temporaries only live to the end of the full expression that makes them spring to life.

In the first code sample, you already have a std::function object in main. That one binds directly to the reference, so you are calling tester with the same referred-to object.

like image 79
StoryTeller - Unslander Monica Avatar answered Oct 15 '22 04:10

StoryTeller - Unslander Monica