std :: function的目标可调用对象可以在执行过程中合法销毁std :: function吗? [英] Can a std::function's target callable legally destroy the std::function during execution?

查看:133
本文介绍了std :: function的目标可调用对象可以在执行过程中合法销毁std :: function吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在另一个问题的评论中,有人指出,常见错误是:

In comments under another question, it was stated that a common mistake is to:


调用 std :: function 调用时会导致持有该对象的对象被破坏

invoke std::function when calling it leads to destruction of object which holds it

显然是危险对象,在健壮的代码中可以避免这样做,这实际上是错误的吗?我在标准中找不到能确保以下内容的措辞:

While clearly a "dangerous" thing to do that would be avoided in robust code, is it actually wrong? I cannot find any wording in the standard that ensures:


  • A std :: function 不得为被目标可调用对象破坏

  • std :: function 的生命周期在执行其目标可调用对象期间不得终止

  • 函子的生存期一般不能在执行过程中结束

  • A std::function must not be destroyed by its target callable
  • A std::function's lifetime must not end during execution of its target callable
  • The lifetime of a functor in general must not end during its execution

据我所知,这是合法且定义明确的(尽管味道不好)执行以下操作:

To my knowledge, it is legal and well-defined (though in poor taste) to do things like the following:

struct Foo
{
   void baz()
   {
      delete this;
      // Just don't use any members after this point
   }
};

int main()
{
   Foo* foo = new Foo();
   foo->baz();
}

这表明,在没有任何重要限制的情况下,我找不到任何限制,

This suggests that, in the absence of any overriding restrictions, none of which I can find, the following would also be technically well-defined:

#include <functional>

struct Bar
{
   std::function<void()> func;
};

int main()
{
   Bar* bar = new Bar();
   bar->func = [&]() { delete bar; };
   bar->func();
}

不是这样吗?如果不是,那么哪个措辞禁止呢?

Is this not the case? If not, which wording prohibits it?

(对于奖励积分,如果自先前的标准以来发生了变化,这将很有趣。)

推荐答案

[res.on.objects] / 2:

[res.on.objects]/2:


如果是对象存取标准库类型,并且对象生命周期的开始
不在访问之前发生,或者
访问没有在对象生命周期结束之前发生,
行为除非另有说明,否则为undefined。 [注意:这甚至将
应用于对象(例如用于线程同步的互斥体)。 —
尾注]

If an object of a standard library type is accessed, and the beginning of the object's lifetime does not happen before the access, or the access does not happen before the end of the object's lifetime, the behavior is undefined unless otherwise specified. [ Note: This applies even to objects such as mutexes intended for thread synchronization. — end note ]

就库而言,成员函数可以访问该对象,直到它返回为止。因此,除非明确授予许可,否则在调用中间销毁对象是不确定的。

As far as the library is concerned, a member function can access the object until it returns. It follows that destroying the object in the middle of such a call is undefined unless permission is explicitly granted.

这篇关于std :: function的目标可调用对象可以在执行过程中合法销毁std :: function吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆