当通过operator()调用时,返回std :: function的std :: function对象如何工作?

时间:2017-07-22 12:48:01

标签: c++

样品:

#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;
}

为什么func(3)可以将3传递给i,这是foo()中lambda的形式参数。我想不出来。谢谢。

1 个答案:

答案 0 :(得分:1)

TL; DR :您不会将您的参数3传递给函数Foo。您将其传递给对象 func方法

下面会有更详细的解释。

首先,我想澄清一下 lambda 是什么。 C ++中的 lambda 只不过是一个匿名的函子类,所以基本上只是一个语法糖。 闭包是lambda类型的一个实例。但是,你经常可以听到单词&#34; lambda&#34;和&#34;关闭&#34;可互换使用。

因此,在您的函数Foo()中,您创建了一个闭包对象l

auto l = [v, r](int i)
{
    std::cout << v << " " << r << " " << i << std::endl;
};

在技术上等同于此代码:

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);

现在,在下一行中返回一个std :: function对象。

return l; // actually creates std::function<void(int)>(l) and returns it

因此,在main函数中,func只是一个对象,用于存储在通话期间获得的值v, r副本Foo()并定义operator(),类似于上面的结构。 因此,调用func(3)实际上是在具体对象函数上调用对象方法,而没有语法糖,它看起来像func.operator()(3)

这里有live example来说明我的观点。

希望这有助于解决您的困惑。