【问题标题】:C++ lambda two copy constructor callsC++ lambda 两个复制构造函数调用
【发布时间】:2016-03-05 10:16:22
【问题描述】:

我有以下代码sn-p。

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

输出是:

A (cA cA 1 dA dA) dA

为什么temp被复制了两次?

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

【问题讨论】:

  • 您缺少function&lt;&gt; 的声明,但我猜它正在那里发生。
  • @PaulEvans 它怎么不见了? #include &lt;functional&gt; 在那里,using namespace std;(虽然实践不佳)在那里。
  • @Angew 对不起-我的错。在错误的目录中构建:(

标签: c++ c++11 visual-c++ lambda copy-constructor


【解决方案1】:

function&lt;void(A)&gt; 有一个具有以下签名的函数调用运算符:operator()(A),即它按值获取参数,因此调用 f(a) 会生成一个副本。

lambda 还按值获取其参数,因此当在 function&lt;void(A)&gt; 调用运算符中调用它时,会生成另一个副本。

如果您为 A 定义移动构造函数,您应该看到初始化 lambda 参数(从 function 创建的第一个副本)可以是移动而不是副本,但前提是类型具有移动构造函数。否则必须复制。

或者,如果您使用std::function&lt;void(const A&amp;)&gt;,则调用运算符将​​通过引用而不是按值获取其参数,因此只制作了一份副本来初始化 lambda 的参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 2018-10-17
    • 2013-04-17
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 2016-03-25
    相关资源
    最近更新 更多