#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; }
没有取消注释这一行// other.m_func = [] {};
程序产生这个输出:
Executing the program…. $demo called terminate called after
throwing an instance of ‘std::bad_function_call’ what():
bad_function_call
移动后std :: function不重置内部函数是否正常?
解决方法
根据C 11 20.8.11.2.1 / 6 [func.wrap.func.con],从现有的std :: function对象移动构造使原始对象“处于具有未指定值的有效状态”.所以基本上不要假设任何事情.只是不要使用原始功能对象,或者如果仍然需要它也不要移动它.