This is a creation in Article, where the information may have evolved or changed.
Copyright <chaishushan#gmail.com>. All rights reserved.//Use of this source code are governed by a bsd-style//license so can be found in the license file. #ifndef _defer_h_#define _defer_h_#include <functional> #include <iostream>////need support c11-std=c++11//DEFER The////statement defines an object that delays the execution of a closure function based on usage:////file* fp = fopen ("Foo.txt", "RT");/if (fp = = NULL) return false;//defer ([&] () {PR Intf ("fclose (FP) \ n"); Fclose (FP); });///char* BUF = new char[1024];//defer ([&] () {printf ("delete buf\n"); delete[] buf;}); ////Defer ([] () {printf ("Defer A:%d\n", __line__); /defer ([] () {printf ("Defer A:%d\n", __line__); /defer ([] () {printf ("Defer A:%d\n", __line__); ///{//Defer ([] () {printf ("Defer B:%d\n", __line__);}); /defer ([] () {printf ("Defer B:%d\n", __line__);}); /defer ([] () {printf ("Defer B:%d\n", __line__);}); /}////Defer ([] () {//printf ("Defer c:\n");//for (int i = 0; i < 3; ++i) {//DEFer ([&] () {defer ([&] () {//printf ("\ti =%d:begin\n", i);//defer ([&] () {printf ("\ti =%d\n ", i); });//printf ("\ti =%d:end\n", i);/}); /}//});////Note:////1. The object defined by defer executes the closure function (destructor)//2 when it goes out of scope. The object defined by defer is different within the same file identifier (generated by line number)//3. Defer may occur with the same name in the global scope (line number is the same)//4. Defer may be executed in advance (at the end of the scope)//5 When judging the statement usage. Defer used in a loop statement is invalid (at the end of the scope)//6. Defer and go language defer are not exactly equivalent////more reference:////http://blog.korfuri.fr/post/go-defer-in-cpp///http://blog.korfuri.fr/ attachments/go-defer-in-cpp/defer.hh//http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx///HTTP golang.org/doc/effective_go.html#defer//http://golang.org/ref/spec#Defer_statements//#define DEFER _defer_action _make/* ([&] () {...}); *///Auto _defer_action_line??? _ = _deferredactionctor ([&] () {...}) #define _defer_action_make auto \ _defer_action_var (_defer_action_line, __line__, _) = _deferredactionctor#define _DEFE R_action_var (A, B, c) _defer_token_cOnnect (A, B, c) #define _defer_token_connect (A, B, C) A # # # # # # c//holds the closure function class _deferredaction {private:std::function& Lt;void () > func_; Template<typename t> friend _deferredaction _deferredactionctor (t&& p); Template<typename t> _deferredaction (t&& p): Func_ (Std::bind (std::forward<t> (p))) {Std::cou T << "NEW 1" << Std::endl; } _deferredaction (); _deferredaction (_deferredaction const&); _deferredaction& operator= (_deferredaction const&); _deferredaction& operator= (_deferredaction&&);p ublic: _deferredaction (_deferredaction&& other ): Func_ (Std::forward<std::function<void () >> (other.func_)) {other.func_ = nullptr; Std::cout << "NEW 2" << Std::endl; } ~_deferredaction () {if (func_) {func_ ();} Std::cout << "DELETE" << Std::endl; }};template<typename t>_deferredaction _deferredactionctoR (t&& p) {return _deferredaction (std::forward<t> (P));} #endif//_defer_h_
Test:
/* * File:main.cpp * author:vicky.h * email:eclipser@163.com */#include "defer.h" #include <iostream>void sayh Ello (const char* name) {printf ("Hello%s\n", name);} void Funtest () {printf ("funtest 1\n"); Defer ([] () {printf ("Defer C:%d\n", __line__);}); Defer ([] () {printf ("Defer C:%d\n", __line__);}); Defer ([] () {printf ("Defer C:%d\n", __line__);}); printf ("Funtest 2\n");} /* * */int main (void) {defer ([] () {printf ("Defer A:%d\n", __line__);}); Defer ([] () {printf ("Defer A:%d\n", __line__);}); Defer ([] () {printf ("Defer A:%d\n", __line__);}); Defer ([] () {SayHello ("Jack");}); {Defer ([] () {printf ("Defer B:%d\n", __line__);}); Defer ([] () {printf ("Defer B:%d\n", __line__);}); Defer ([] () {printf ("Defer B:%d\n", __line__);}); Std::cout << "In code scope" << Std::endl; } std::cout << "\ n---------------------------" << Std::endl; Std::cout << "Done 1" << Std::endl; Std::cout << "Done 2" << Std::endl; Std::cout << "Done 3" << Std::endl; Throw "Exception happen"; Std::cout << "\ n---------------------------" << Std::endl; Funtest (); return 0;}
Git:http://git.oschina.net/eclipser/defer4cpp.git
Note that the above code needs to support c++11:-std=c++11
Output:
NEW 1
NEW 1
NEW 1
NEW 1
NEW 1
NEW 1
NEW 1
In Code scope
Defer b:42
DELETE
Defer b:41
DELETE
Defer b:40
DELETE
---------------------------
Done 1
Done 2
Done 3
---------------------------
Funtest 1
NEW 1
NEW 1
NEW 1
Funtest 2
Defer c:22
DELETE
Defer c:20
DELETE
Defer c:18
DELETE
Hello, Jack.
DELETE
Defer a:35
DELETE
Defer a:33
DELETE
Defer a:31
DELETE
Run finished; Exit value 0; Real-time: 20ms; User: 0ms; System: 0MS