简体   繁体   English

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

[英]Move constructor called with lambda

I am trying to understand how lambdas work in C++ in depth. 我试图了解lambdas如何在C ++中深入工作。 I have written the following piece of code. 我写了下面这段代码。

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

The output is below. 输出如下。

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

This is quite clear to me, except for the 'mA52' move constructor call. 除了“mA52”移动构造函数调用之外,这对我来说非常清楚。 Note that I am using variable capture by value, so without the move constructor, the copy-constructor would be called here. 请注意,我按值使用变量捕获,因此如果没有移动构造函数,则会在此处调用copy-constructor。 Why is there an additional copy/move at this step? 为什么在这一步有额外的复制/移动? One would expect the object to be copied only once when fun is passed by value as an argument to f . fun作为f的参数传递fun时,人们会期望只复制一次该对象。 Furthermore, the first copy of the object is immediately destroyed. 此外,该对象的第一个副本立即被销毁。 Why? 为什么? What is this intermediary copy? 这个中间副本是什么?

Let's call your lambda type L . 我们叫你的lambda L型。 It's unnamed, but it gets confusing to refer to it without a name. 它没有命名,但是如果没有名字就引用它会让人感到困惑。

The constructor std::function<void(A)>(L l) takes L by value. 构造函数std::function<void(A)>(L l)L值。 This involves creating a copy of the original fun . 这涉及创建原始fun的副本。

The constructor then moves the lambda from l into some storage managed by the std::function<void(A)> wrapper. 然后构造函数将lambda从l移动到由std::function<void(A)>包装器管理的某个存储中。 That move also involves moving any captured entities. 这一举措还涉及移动任何被捕获的实体。

std::function<void(A)> takes the function object you pass to it by value (this is the cA42 in your output). std::function<void(A)>获取您通过值传递给它的函数对象(这是输出中的cA42)。 It then moves the function object in to its internal storage (this is the mA52). 然后它将功能对象移动到其内部存储器(这是mA52)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM