我有以下代码片段。

#include <iostream>
#include <functional>
using namespace std;

struct A
{
    A() { cout << "A "; data = 1; }
    A(const A& a) { cout << "cA "; data = a.data; }
    ~A() { cout << " dA"; }
    int data;
};

void f(A& a, function<void(A)> f)
{
    cout << "(";
    f(a);
    cout << ")";
}

int main()
{
    A temp;
    auto fun = [](A a) {cout << a.data;};
    f(temp, fun);
}

输出为:



为什么temp复制两次?

我正在使用Visual C++(vc140)。

最佳答案

function<void(A)>具有一个具有以下签名的函数调用运算符:operator()(A),即它按值接受参数,因此调用f(a)会创建一个拷贝。

lambda也按值接受其参数,因此在function<void(A)>调用运算符中调用该lambda时,将得到另一个拷贝。

如果为A定义了一个移动构造函数,则应该看到初始化lambda参数(从function生成的第一个拷贝开始)可以是一个移动而不是一个拷贝,但仅当该类型具有移动构造函数时才可以。否则,必须将其复制。

或者,如果您使用std::function<void(const A&)>,则调用运算符将​​按引用而不是按值获取其参数,因此只有一个拷贝用于初始化lambda的参数。

09-07 08:38