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.
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.
Letter. λ • (l) (lowercase, uppercase Λ) The lower case letter lambda (λάμδα), the eleventh letter of the modern Greek alphabet.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With