在调用过程中删除std :: function

时间:2018-08-09 20:22:13

标签: c++ c++11 c++14

在调用过程中销毁/删除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;
}

2 个答案:

答案 0 :(得分:6)

[res.on.objects]p2对此没有定义:

  

如果访问了标准库类型的对象,则开始   对象的生存期不会在访问之前发生,否则   访问不会在对象生存期结束之前发生,   除非另有说明,否则行为是不确定的。

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

答案 1 :(得分:3)

您的代码(您要问的一点,即成员函数中对象的破坏)大致等同于

struct A
{
  void f() { delete this; }
}

int main()
{
  A* a = new A;
  a.f();
}

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

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