The specialization std::function<R(Args...)>
has a call operator with the following declaration:
R operator()(Args...) const;
In your case, this means that the operator takes A
. As such, calling f(a)
results in a copy due to the pass-by-value semantics. However, the underlying foo
target also accepts its argument by value. Thus there will be a second copy when the parameter to f
is forwarded to foo
.
This is by design, and in fact if A
had a move constructor there would be only one copy followed by a move construction -- and calling f(std::move(a))
would only result in two move constructions. If you feel that two copies are too much you need to reconsider whether both foo
and f
should take A
instead of e.g. A const&
, and/or whether A
can have a sensible move constructor.
You can also do std::function<void(A const&)> f = &foo;
without modifying foo
. But you should reserve that for the case where modifying foo
is beyond your control, and/or making A
cheaply move constructible is not an option. There is nothing wrong with passing by value in C++11, so I suggest that either both should take A
, or both should take A const&
.