#include #include // In most cases, the following are preferred for efficiency. Some // cases may require the flexibility of the general unwind_protect // mechanism defined above. // Perform action at end of the current scope when unwind_action // object destructor is called. // // For example: // // void fcn (int val) { ... } // // ... // // { // int val = 42; // // // template parameters, std::bind and std::function provide // // flexibility in calling forms (function pointer or lambda): // // unwind_action act1 (fcn, val); // unwind_action act2 ([val] (void) { fcn (val); }); // } // // NOTE: Don't forget to provide a name for the unwind_action // variable. If you write // // unwind_action /* NO NAME! */ (...); // // then the destructor for the temporary anonymous object will be // called immediately after the object is constructed instead of at // the end of the current scope. class unwind_action { public: template unwind_action (F&& fcn, Args&&... args) : m_fcn (std::bind (fcn, args...)) { } // No copying! unwind_action (const unwind_action&) = delete; unwind_action& operator = (const unwind_action&) = delete; ~unwind_action (void) { m_fcn (); } private: std::function m_fcn; }; int main (void) { int x = 13; std::cerr << "initial value of X in MAIN: " << x << std::endl; { // Capture X by value in the lambda expression. The lambda // expression in ACT1 has a copy of X so any later changes to X in // MAIN won't affect that value. unwind_action act1 ([x] (void) { std::cerr << "X copied in ACT1 lambda: " << x << std::endl; }); // Capture X by reference in the lambda expression. The lambda // expression in ACT2 doesn't have a local copy, so any later // change to the referenced X in MAIN will be reflected in ACT2 // (the X in ACT2 is not a separate value). unwind_action act2 ([&x] () { std::cerr << "X referenced in ACT2 lambda: " << x << std::endl; }); // Capture X by value in the unwind_action object ACT3. ACT3 has // a copy of X so any later changes to X in MAIN won't affect that // value. unwind_action act3 ([] (int x) { std::cerr << "X copied in ACT3 unwind_action object: " << x << std::endl; }, x); // Change the value of X in the parent. x = 42; std::cerr << "new value of X in MAIN: " << x << std::endl; std::cerr << "Check values when the unwind_actions run:" << std::endl; } return 0; }