移动使用lambda调用的构造函数

时间:2015-12-02 11:19:03

标签: c++ c++11 visual-c++ lambda move-semantics

我试图理解lambdas如何在C ++中深入工作。我写了下面这段代码。

#include <iostream>
#include <functional>

struct A
{
    A() { std::cout << "A" << (data = ++count) << ' '; }
    A(const A& a) { std::cout << "cA" << (data = a.data + 20) << ' '; }
    A(A&& a) { std::cout << "mA" << (data = std::move(a.data) + 10) << ' '; }
    ~A() { std::cout << "dA" << data << ' '; }
    int data;
    static int count;
};

int A::count = 0;

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

int main()
{
    A temp, x;
    auto fun = [=](A a) {std::cout << a.data << '|' << x.data << ' ';};
    std::cout << "| ";
    f(temp, fun);
    std::cout << "| ";
}

输出低于。

  

A1 A2 cA22 | cA42 mA52 dA42(cA21 mA31 31 | 52 dA31 dA21)dA52 | dA22 dA2 dA1

除了&#39; mA52&#39; 移动构造函数调用之外,我很清楚这一点。请注意,我按值使用变量捕获,因此如果没有移动构造函数,则会在此处调用copy-constructor。为什么在这一步有额外的复制/移动?当fun作为f的参数传递app.use(express.static(path.join(__dirname, 'public'))); 时,人们会期望只复制一次该对象。此外,该对象的第一个副本立即被销毁。为什么?什么是中间副本?

2 个答案:

答案 0 :(得分:2)

让我们调用你的lambda类型L。它没有命名,但是在没有名字的情况下引用它会让人感到困惑。

构造函数std::function<void(A)>(L l)按值L获取。这涉及创建原始fun的副本。

然后,构造函数将lambda从l移动到由std::function<void(A)>包装器管理的某个存储中。这一举措还涉及移动任何被捕获的实体。

答案 1 :(得分:1)

std::function<void(A)>获取您通过值传递给它的函数对象(这是输出中的cA42)。然后它将功能对象移动到其内部存储器(这是mA52)。