What I understand as a typical use of std::function
#include <iostream>
#include <functional>
using namespace std;
class C {
public:
C() { cout << "CREATING" << endl; }
C(const C&) { cout << "COPY C "<< endl; };
C(C&&) { cout << "MOVE C " << endl; };
~C() { cout << "DELETING"<< endl; }
C& operator =(const C&) {
cout << "COPY A " << endl; return *this;
};
C& operator =(C&&) {
cout << "MOVE A" << endl; return *this;
};
void operator ()() const { cout << "CALLING" << endl; }
};
int main(int argc, char *argv[]) {
function<void()> f = C();
f();
return 0;
}
yields following output
CREATING
MOVE C
DELETING
CALLING
DELETING
Apparently, temporary object is created on stack and then moved into function object. If move constructor is not provided, it is copied instead.
Is there a standard way of setting the target without need for a temporary object?
The way that function
is constructed from any functor F f
is stipulated by the standard in §20.9.11.2.1 as (assuming f
is a non-null, emphasis mine):
*this
targets a copy off
initialized withstd::move(f)
So there is no way to in-place construct a function
. That leaves you with a choice between incurring that move:
function<void()> f1 = C{};
Or passing in some wrapper around C
that is cheaper to move/copy, either one in which you manage externally:
C manage_me;
function<void()> f2 = std::ref(manage_me);
... or an allocated one bound to operator()
:
function<void()> f3 = std::bind(&C::operator(), std::make_shared<C>());
That last one could cause some headaches if operator()
happens to be overloaded, as you'd have to cast it to the right type, which is an issue that none of the previous versions have to deal with.
function<void()> f4 = std::bind(
static_cast<void(C::*)()>(&C::operator()),
std::make_shared<C>()
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With