Std :: function to member object function and object lifetime

If I have an instance of std::function associated with a member function of an instance of an object, and this instance of the object goes out of scope and is otherwise destroyed, my std::function object will now be considered a bad pointer, which will fail if caused by?

Example:

 int main(int argc,const char* argv){ type* instance = new type(); std::function<foo(bar)> func = std::bind(type::func,instance); delete instance; func(0);//is this an invalid call } 

Is there anything in the standard that indicates what should happen? My guess is that it will generate and exclude, because the object no longer exists

EDIT: Does the standard indicate what should happen?

Is this behavior undefined?

EDIT 2:

 #include <iostream> #include <functional> class foo{ public: void bar(int i){ std::cout<<i<<std::endl; } }; int main(int argc, const char * argv[]) { foo* bar = new foo(); std::function<void(int)> f = std::bind(&foo::bar, bar,std::placeholders::_1); delete bar; f(0);//calling the dead objects function? Shouldn't this throw an exception? return 0; } 

By running this code I get an output value of 0;

+6
source share
1 answer

What happens is undefined behavior.

In the call to bind() , an object will be returned that contains a copy of instance , so when called, func(0) will effectively call:

 (instance->*(&type::func))(0); 

Displaying an invalid pointer, as you would if there were instance delete d, this is undefined behavior. It will not throw an exception (although it is undefined, so it could, who knows).

Please note that there is no placeholder in your call:

 std::function<foo(bar)> func = std::bind(type::func, instance, std::placeholders::_1); // ^^^^^^^ here ^^^^^^^^^ 

Without this, you cannot call func(0) even with an unused instance.

Updating the sample code to better illustrate what happens:

 struct foo{ int f; ~foo() { f = 0; } void bar(int i) { std::cout << i+f << std::endl; } }; 

With this added destructor, you can see the difference between copying the pointer (in f ) and copying the object pointed to (in g ):

 foo* bar = new foo{42}; std::function<void(int)> f = std::bind(&foo::bar, bar, std::placeholders::_1); std::function<void(int)> g = std::bind(&foo::bar, *bar, std::placeholders::_1); f(100); // prints 142 g(100); // prints 142 delete bar; f(100); // prints 100 g(100); // prints 142 still, because it has a copy of // the object bar pointed to, rather than a copy // of the pointer 
+6
source

Source: https://habr.com/ru/post/981309/


All Articles