Is it safe to change a function pointer (std::function) inside a called function?

孤街醉人 提交于 2019-11-30 22:23:24

问题


I have a std::function pointing to a function. Inside this function I change the pointer to another 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();
}

I can't see any problem and it works just fine (see here), however I'm not sure if this is legal to do so. Is there anything I am missing? Maybe in the c++ standard draft (I checked quickly but didn't see anything so far).


回答1:


This is legal with function pointers.

When you assign or construct a std::function with a target, it creates a copy of the target. In the case of assigning a function to the std::function, this in effect stores a function pointer as the target object.

When you invoke operator(), it is required to return what would happen if you invoked that the target with the arguments.

Within that "body" of the copy of the function object stored as a copy in the std::function, if you reassign to the std::function, this destroys the old target function object.

Destroying a function pointer has no impact on the validity of code executed within the function pointed to.

However, if you had stored function objects (lambdas, manual ones, other std::functions, std::bind, etc), at the point of assignment you'd run into the usual rules of running a method in a class when this is destroyed. In short, you would no longer be able to do anything that relied on "local state" of your instance.

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();
}

live example.

So as you can see, this can be fragile.




回答2:


It may come back to bite you if you do it without due consideration and in code documentation, but there is no logical reason why it won't work.

In c++, the address of a function is not needed, either within the function in the return coding.

If it didn't work in some language the complier probably wouldn't accept it - if it's a half decent compiler.



来源:https://stackoverflow.com/questions/42651046/is-it-safe-to-change-a-function-pointer-stdfunction-inside-a-called-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!