Li Chen
Li Chen

Reputation: 5270

How does a std::function object which return a std::function work when call by operator()?

Sample:

#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

Answers (1)

Vasiliy Galkin
Vasiliy Galkin

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

Related Questions