I need to pass a std::function as a void* pointer to be executed asynchronously, so I create a std::function on the heap. Is it safe to delete the std::function object from inside the function body?
Please see the following example:
using T = std::function<void()>;
void fun(int data)
{
T* t = new T([&t, data]()
{
//do something
delete t;
}
ExecuteAsync(t);
}
Mistake in capturing
&tFirstly, note that capturing
[&t]is a mistake.&twould dangle whenfunreturns. Either you'd need to allocate thestd::functionfirst, or you'd need to use C++23 explicit object member functions to make this work:Assuming you did one of these two things ...
Delete self in
std::functionPedantically speaking, it is not safe to do. [func.wrap.func]
operator()is only said to returnINVOKE<R>(...), but it's not guaranteed to consist of just areturnstatement that does that. Hypothetically, it would be allowed to implement it like(1):Reading the memory of an object whose lifetime has ended is obviously UB, so this would break your code. However, no standard library does this, and there is no obvious reason why anyone would.
In practice, what you're doing will work, for the same reason that
delete thisis allowed. See Is "delete this" allowed in C++?.(1) A Returns paragraph only states the returned value. It does not impose further requirements on the implementation.
Further notes on design
However, if you have to ask yourself, maybe it's not a good idea from a code style perspective. If you instead did:
... where
ExecuteAsyncobtains ownership of astd::functionand also destroys it once executed, it would be much more obvious how and why it's correct. At the very least, you could handExecuteAsyncastd::unique_ptr.