2

I am trying to understand how lambdas work in C++ in depth. 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 | cA42 mA52 dA42 ( cA21 mA31 31|52 dA31 dA21 ) dA52 | dA22 dA2 dA1

This is quite clear to me, except for the 'mA52' move constructor call. Note that I am using variable capture by value, so without the move constructor, the copy-constructor would be called here. 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. Furthermore, the first copy of the object is immediately destroyed. Why? What is this intermediary copy?

2 Answers 2

2

Let's call your lambda type 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. This involves creating a copy of the original fun.

The constructor then moves the lambda from l into some storage managed by the std::function<void(A)> wrapper. That move also involves moving any captured entities.

Sign up to request clarification or add additional context in comments.

Comments

1

std::function<void(A)> takes the function object you pass to it by value (this is the cA42 in your output). It then moves the function object in to its internal storage (this is the mA52).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.