我需要传递一个
std::function
作为要异步执行的 void
指针,因此我在堆上创建了一个 std::function
。删除函数体内的 std::function
对象是否安全?请看下面的例子:
using T = std::function<void()>;
void fun(int data)
{
T* t = new T([&t, data]()
{
//do something
delete t;
}
ExecuteAsync(t);
}
迂腐地说,这样做并不安全。 [func.wrap.func]
operator()
仅表示返回 INVOKE<R>(...)
,但不能保证它只包含执行此操作的 return
语句。
假设,它可以像(1):那样实现
R operator()(ArgTypes... args) {
R result = INVOKE<R>(f, std::forward<ArgTypes>(args)...);
// read memory in this object
return result;
}
读取生命周期已结束的对象的内存显然是 UB,所以这会破坏你的代码。 然而,没有标准库这样做,也没有明显的理由说明为什么有人会这样做。
实际上,您所做的事情将会起作用,这与允许使用
delete this
的原因相同。请参阅C++ 中允许“删除此”吗?。
但是,如果你必须问自己,从代码风格的角度来看,也许这不是一个好主意。 如果你这样做:
ExecuteAsync(std::move(my_function));
...其中
ExecuteAsync
获得 std::function
的所有权并在执行后销毁它,那么它的正确性和原因会更加明显。
至少,你可以递给ExecuteAsync
一个std::unique_ptr
。
(1) A Returns 段落 仅说明返回值。它没有对实施提出进一步的要求。