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 << "
";
if (next) fun = *next;
// undefined behavior:
// std::cout << name << "
";
}
};
bob foo = {"foo"};
bob bar = {"bar", &foo};
int main() {
fun = bar;
fun();
fun();
}
live example.
So as you can see, this can be fragile.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…