C++ 当绑定对象过期时,std::bind创建的函子的行为是否定义良好?

C++ 当绑定对象过期时,std::bind创建的函子的行为是否定义良好?,c++,language-lawyer,stdbind,C++,Language Lawyer,Stdbind,以下代码的行为是否定义良好?f()调用的行为如何 #include <functional> #include <iostream> struct A { void shout() { std::cout <<"shout"; } }; int main() { std::function<void()> f; { A a; f = std::bind(&A::s

以下代码的行为是否定义良好?
f()
调用的行为如何

#include <functional>
#include <iostream>

struct A
{
  void shout()
  {
      std::cout <<"shout";
  }
};


int main()
{
    std::function<void()> f;
    {
        A a;
        f = std::bind(&A::shout, &a);
    }

    f();  // what happens here?
}
#包括
#包括
结构A
{
无效呼喊()
{

std::cout您的代码最终在函数包装器中存储了一个悬空引用(指向不再存在的对象),调用函数会导致未定义的行为

如果原始对象的寿命不如包装器长,则始终可以在包装器中存储对象的副本:

f = std::bind(&A::shout, a);
//                      ^^^ copy

要显示未定义,请注意存储的地址变为无效指针值-:

当到达存储区域的持续时间结束时 所有指针的值,这些指针表示 解除分配的存储将成为无效的指针值([basic.component])

在对绑定函子的调用中,该指针被取消引用以执行成员函数调用,适用于:

通过无效指针值进行间接寻址并传递无效 指向解除分配函数的指针值具有未定义的行为


相反,您可以为每个值绑定
a
(省略符号)。

此外,对成员函数的调用需要一个对象[class.mfct.non static]p1。请注意,如果
shout
是静态的,则代码没有UB AFAIK。(如果发生间接寻址,则存在一个基本问题*/*的时间。)@dyp Edit:哎呀,我以为你提到了/2。p2有DR吗?@dyp发生了间接寻址,这会导致未定义的行为。我们可以像使用空指针一样放松,允许丢弃间接寻址的值,但这不是我们想要的。@dyp/2的缺陷不在于它不一致,而在于它应该ld涵盖了传递无效左值的情况。(与其说是缺陷,不如说是需要澄清。/1对于需要的对象不够明确。)