C ++ lambdas传递

时间:2014-03-22 10:13:18

标签: c++11 lambda

这只是一个理论问题。当我执行此代码时:

#include <functional>
#include <cstdio>

struct A {

    int value = 100;

    A() {
        printf("A\n");
    }

    A(const A& a) {
        printf("copy A\n");
    }

    ~A() {
        printf("~A\n");
    }
};

void function(std::function<int()> lambda) {
    printf("%d\n", lambda());
}

int main()
{
    A a;
    auto lambda = [a]() -> int {
        return a.value;
    };

    function(lambda);

    return 0;
}

输出是这样的:

A
copy A
copy A
copy A
100
~A
~A
~A
~A

我的问题是为什么结构A被复制3次而不是2次? 一个副本采用lambda捕获,第二个采用传递参数到函数,第三个采用什么?

1 个答案:

答案 0 :(得分:2)

如果您按如下方式更改代码,您将看到相同数量的复制操作:

int main()
{
    A a;
    auto&& lambda = [a]() -> int {
        return a.value;
    };
    std::function<int()>{lambda};
}

创建lambda时会发生第一次复制/移动构造。第二个和第三个复制/移动构造在构造 std :: function 期间发生。根据N3690, std :: function 使用的构造函数如下所示:

template <class F> function(F);

这意味着,在将参数传递给构造函数时,传递的参数将被复制/移动一次。在构造函数中,它将被另一次复制/移动以进行类型擦除。

如果构造函数使用引用(例如使用完美转发),则只能看到两个复制/移动构造。但是,我不知道为什么在这种情况下没有使用它。

template <typename Arg> function(Arg&&);