在被调用的函数中更改函数指针(std :: function)是否安全?

use*_*087 14 c++ c++11 std-function

std::function指着一个函数.在这个函数内部,我将指针更改为另一个函数.

std::function<void()> fun;

void foo() {
    std::cout << "foo\n";
}

void bar() {
    std::cout << "bar\n";
    fun = foo;
}

int main() {
    fun = bar;
    fun();
    fun();
}
Run Code Online (Sandbox Code Playgroud)

我看不出任何问题,它工作正常(见这里),但我不确定这是否合法.有什么我想念的吗?也许在c ++标准草案中(我快速检查但到目前为止没有看到任何内容).

Yak*_*ont 12

这对于函数指针是合法的.

当您std::function使用目标分配或构造a 时,它会创建目标的副本.在为函数赋值的情况下std::function,这实际上将函数指针存储为目标对象.

当您调用时operator(),如果您使用参数调用目标,则需要返回会发生的情况.

在函数对象的副本"body"中存储为副本std::function,如果你重新分配,则会std::function破坏旧的目标函数对象.

销毁函数指针不会影响在指向的函数内执行的代码的有效性.

但是,如果你已经存储了函数对象(lambda,manual,其他std::functions std::bind等),那么在赋值时你会遇到通常的规则,即在类中this被破坏时运行一个方法.简而言之,您将无法再依赖实例的"本地状态"执行任何操作.

std::function<void()> fun;
struct bob {
  std::string name;
  bob* next = 0;
  void operator()() const {
    std::cout << name << "\n";
    if (next) fun = *next;
    // undefined behavior:
    // std::cout << name << "\n";
  }
};
bob foo = {"foo"};
bob bar = {"bar", &foo};

int main() {
  fun = bar;
  fun();
  fun();
}
Run Code Online (Sandbox Code Playgroud)

实例.

所以你可以看到,这可能很脆弱.