function<void(A)> has a call function operator with this signature: operator()(A) i.e. it takes its argument by value, so calling f(a) makes a copy.
lambda also takes its argument by value, so when it is called inside the function<void(A)> statement function<void(A)> , another copy is created.
If you define a move constructor for A , you should see that initializing the lambda argument (from the first copy made by function ) can be a move, not a copy, but only if the type has a move constructor. Otherwise, it must be copied.
Alternatively, if you use std::function<void(const A&)> , then the call operator will take its argument by reference not by value, therefore there will only be one copy to initialize the lambda argument.
source share