프로그래밍 검색 블로그

함수가 끝날때 같이 해제하기 defer 본문

C++ 유틸

함수가 끝날때 같이 해제하기 defer

코딩조무사 2017. 10. 6. 20:26

go언어의 defer와 거의 비슷하게 제작하였다. 

C++에서는 finally를 사용할수 있지만 꼭 finally에 넣을수 없는 상황도 있기 때문에

아무 함수나 넣을수 있게 하는 defer를 제작

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <functional>
#include <type_traits>
template<typename _Func>
struct Defer{
    using value_type = _Func;
    using const_reference = typename std::add_lvalue_reference<typename std::add_const<_Func>>::type;
    
    value_type defer_function;
    Defer(const_reference f) : defer_function(f){}
    Defer(value_type&& f) : defer_function(f){}
    ~Defer(){ run_function(std::is_assignable<_Func, std::nullptr_t>()); }
    
    inline void run_function(std::false_type /*lambda function, const function pointer*/){
        defer_function();
    }
    inline void run_function(std::true_type /*std::function<>, function pointer*/){
        if(defer_function) {
            defer_function();
        }
    }
};
 
template<typename _Func>
auto make_defer(_Func&& f) -> Defer<_Func> {
    return Defer<_Func>(std::forward<_Func>(f));
}
template<typename _Func>
auto make_defer(typename std::add_lvalue_reference<typename std::add_const<_Func>>::type f) -> Defer<_Func>{
    return Defer<_Func>(std::forward<_Func>(f));
}
#define MAKE_TOKEN_PASTE(x, y) x##y
#define MAKE_TOKEN(x, y) MAKE_TOKEN_PASTE(x, y)
#define defer(__CODE__BLOCK__) auto MAKE_TOKEN(_temp_defer,__LINE){make_defer([=]{__CODE__BLOCK__})}
 
cs




테스트


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
void foo(){
    
}
int main(){
    int* a = new int(3);
    defer({//기본사용
        delete a;
    });
    
    std::function<int()> b;
    using myfp = void(*)();
    myfp cc= nullptr;
    
    auto deferd = make_defer(&foo); //if 체크로 실행하지 않음;
    auto deferd2 = make_defer(cc); //if 체크로 실행하지 않음;
 
}
cs


간단하게 사용하려면 정의된 define
defer({
여기에 할일을 정의하고
});

함수 자체를 넘길때는 make_defer로 넘길 수 있다. 

물론 std::function이나 대입가능한 함수포인터가 들어갈때는 null체크를 해서 

에러가 안나게 한다. 


'C++ 유틸' 카테고리의 다른 글

C++ 컬렉션 필터링  (0) 2017.10.07
시간 관련 API  (0) 2017.10.04
stringprintf string반환 sprintf 2  (0) 2017.10.04
stringprintf string반환 sprintf 1  (0) 2017.10.04
C++ Traits  (0) 2017.10.03
Comments