Performs std :: function reset its internal function after moving

#include <iostream> using namespace std; #include <functional> template <class F> class ScopeExitFunction { public: ScopeExitFunction(F& func) throw() : m_func(func) { } ScopeExitFunction(F&& func) throw() : m_func(std::move<F>(func)) { } ScopeExitFunction(ScopeExitFunction&& other) throw() : m_func(std::move(other.m_func)) { // other.m_func = []{}; } ~ScopeExitFunction() throw() { m_func(); } private: F m_func; }; int main() { { std::function<void()> lambda = [] { cout << "called" << endl; }; ScopeExitFunction<decltype(lambda)> f(lambda); ScopeExitFunction<decltype(lambda)> f2(std::move(f)); } return 0; } 

without uncommenting this line // other.m_func = []{}; the program produces this conclusion:

Program execution .... $ demo is called terminate called after throwing an instance of 'std :: bad_function_call' what (): bad_function_call

Is it normal that std :: function does not reset its internal function when moving?

+6
source share
2 answers

According to C ++ 11 20.8.11.2.1 / 6 [func.wrap.func.con], move-constructing from an existing std::function object leaves the original object "in an acceptable state with an undefined value", therefore, in principle, I take nothing . Just don’t use the original function object or move from it if you still need it.

+10
source

Is it normal that std :: function does not reset its internal function when moving?

In contrast, in your case, it is resetting an internal function, meaning that the internal descriptor is set to zero, and std::function no longer a real function. And since this happened, calling operator() does not go well.

+4
source

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


All Articles