std::function 的目标可调用在执行期间可以合法地破坏 std::function 吗?

Ast*_*ngs 7 c++ language-lawyer c++17

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

调用std::function它时调用会导致销毁它的对象

虽然在健壮的代码中显然可以避免这种“危险”的事情,但它实际上是错误的吗?我在标准中找不到任何确保以下内容的措辞:

  • Astd::function不得被其目标可调用对象销毁
  • Astd::function的生命周期不能在其目标可调用对象执行期间结束
  • 函子的生命周期一般不能在其执行期间结束

据我所知,执行以下操作是合法且明确的(尽管品味不佳):

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

int main()
{
   Foo* foo = new Foo();
   foo->baz();
}
Run Code Online (Sandbox Code Playgroud)

这表明,在没有任何压倒一切的限制的情况下,我找不到任何一个,以下在技术上也是明确定义的:

#include <functional>

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

int main()
{
   Bar* bar = new Bar();
   bar->func = [&]() { delete bar; };
   bar->func();
}
Run Code Online (Sandbox Code Playgroud)

不是这样吗?如果不是,哪个措辞禁止它?

(对于奖励积分,如果这比以前的标准有所改变,那将会很有趣。)

T.C*_*.C. 1

[对象上的解析]/2:

\n
\n

如果访问标准库类型的对象,并且该对象的生命周期的开始\n未发生在该访问之前,或者\n访问未发生在该对象的生命周期结束之前\n,则该行为是未定义的,除非另有指定。[ 注意:这甚至适用于用于线程同步的互斥体等对象。\xe2\x80\x94\n结束注释]

\n
\n

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

\n