Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ lambda two copy constructor calls

I have the following code snippet.

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

The output is:

A (cA cA 1 dA dA) dA

Why is temp copied twice?

I am using Visual C++ (vc140).

like image 984
Igor Ševo Avatar asked Dec 01 '15 13:12

Igor Ševo


1 Answers

function<void(A)> has a function-call operator with this signature: operator()(A) i.e. it takes its argument by value, so calling f(a) makes a copy.

The lambda also takes its argument by value, so when that is called inside the function<void(A)> call operator another copy gets made.

If you define a move constructor for A you should see that initializing the lambda argument (from the first copy made by the function) can be a move instead of a copy, but only if the type has a move constructor. Otherwise it has to be copied.

Alternatively, if you use std::function<void(const A&)> then the call operator will take its argument by reference not by value, so there is only one copy made, to initialize the argument of the lambda.

like image 148
Jonathan Wakely Avatar answered Sep 30 '22 01:09

Jonathan Wakely