在调用过程中删除 std::函数

Deleting a std::function in the middle of invocation

本文关键字:函数 std 删除 调用 过程中      更新时间:2023-10-16

在调用过程中销毁/删除 std::function 是未定义的行为吗?

class Event {
public:
Event(std::function<void()> f) : func(std::move(f)) {}
~Event() {}
std::function<void()> func;
};
int main()
{
std::vector<Event> events;
auto func = [&]() {
events.pop_back();  
std::cout << "event" << std::endl;
// do more work  
};
events.emplace_back(std::move(func));
events[0].func();
return 0;
}

这是由 [res.on.objects]p2 未定义的:

如果访问了标准库类型的对象,并且开头 对象的生存期不会在访问之前发生,或者 在对象的生存期结束之前不会进行访问,即 除非另有指定,否则行为是未定义的。

在这种情况下,"访问"包括对std::function函数调用运算符的调用。std::function对象的生存期在访问过程中的pop_back()调用处结束。因此,访问不会在对象的生存期结束之前发生,并且行为是未定义的。

你的代码(你问的位,即成员函数内对象的破坏(大致等效于

struct A
{
void f() { delete this; }
}
int main()
{
A* a = new A;
a.f();
}

这确实有效。当引用计数在其unref函数中达到零时,引用计数资源可以执行类似操作。

请注意,您可能需要重新考虑像这样将事件列表和事件本身捆绑在一起。事件不应知道其环境(事件队列(。

相关文章: