#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 uncomment this line // other.m_func = []{};
the program produce this output :
Executing the program.... $demo called terminate called after throwing an instance of 'std::bad_function_call' what(): bad_function_call
is it normal that std::function doesn't reset his internal function when moved ?
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 a valid state with an unspecified value". So basically don't assume anything. Just don't use the original function object, or don't move from it if you still need it.
is it normal that std::function doesn't reset his internal function when moved ?
On the contrary, in your case it does reset the internal function, meaning the internal handle is set to zero, and the std::function
is not a real function any more. And since that happened the call to operator()
does not go well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With