Reputation: 5270
#include "stdafx.h"
#include <functional>
#include <iostream>
#include <string>
std::function<void(int)> Foo()
{
int v = 1;
int r = 2;
auto l = [v, r](int i)
{
std::cout << v << " " << r << " " << i << std::endl;
};
return l;
}
int main()
{
auto func = Foo();
func(3);
return 0;
}
Why func(3)
can pass 3
to i which is the formal argument of the lambda in Foo(). I can't think out. thanks.
Upvotes: 0
Views: 75
Reputation: 2036
TL;DR: You don't pass your argument 3 into a function Foo. You pass it to a method of an object func
.
A bit more detailed explanation is below.
First of all, I would like to clarify what a lambda is. A lambda in C++ is nothing more than an anonymous functor class, so essentially just a syntactic sugar. A closure is an instance of a lambda type. However, quite often you can hear words "lambda" and "closure" being used interchangeably.
So within your function Foo()
you create a closure object l
auto l = [v, r](int i)
{
std::cout << v << " " << r << " " << i << std::endl;
};
which would be technically equivalent to this code:
struct Functor
{
Functor(int v, int r) : v_(v), r_(r) {}
void operator ()(int i) const {
std::cout << v_ << " " << r_ << " " << i << std::endl;
}
private:
int v_;
int r_;
};
Functor l(v, r);
Now, on the next line you return an std::function object.
return l; // actually creates std::function<void(int)>(l) and returns it
So in your main
function a func
is just an object which stores copies of values v, r
obtained during a call to Foo()
and defines operator()
, similar to the struct above.
Therefore, calling func(3)
you actually invoke an object method on a concrete object func, and without syntactic sugar it looks like func.operator()(3)
.
Here's a live example to illustrate my point.
Hope that helps to resolve your confusion.
Upvotes: 1