问题
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::function
s, 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