C++11版本的ScopeGuard

近来闲,看Loki库的ScopeGuard实现,为了不同函数的参数数量,要实现N个类似的模板类,各种麻烦。
C++11带来了变长模板参数,借助模板元编程的编译期递归技术,实现了一个简单的C++11版本的ScopeGuard类,在vs2013和gcc4.8.1编译器下编译通过,如下是代码:
 #include<typeinfo> 
#include<tuple> 
#include<functional>
#include<iostream>
using namespace std;
 
 
template<int N>
class Execute
{
public:
template<typename F, typename T, typename...Ps>
static void execute(F&&f, T&&t, Ps&&...ps)
{
Execute<N - 1>::execute(f, std::forward<T>(t), std::get<N - 1>(std::forward<T>(t)), ps...);
}
};
 
template<>
class Execute<0>
{
public:
template<typename F, typename T, typename...Ps>
static void execute(F&&f, T&&t, Ps&&...ps)
{
f(ps...);
}
};
 
template<typename Func, typename...Paras>
class ScopeGuard
{
public:
static ScopeGuard<Func, Paras...>
MakeScopeGurad(Func func, Paras...para)
{
return  ScopeGuard(std::move(func), std::move(para)...);
}
 
public:
ScopeGuard(Func&&f, Paras&&...p) :_func(f), _para(p...) { };
 
 
public:
~ScopeGuard()
{  
  Execute<::std::tuple_size<tuple<Paras...>>::value >::execute(_func, _para); 
};
 
 
private: 
Func _func;
tuple<Paras...> _para;
};
 
 
template<typename Func, typename...Paras>
auto MakeScopeGurad(Func func, Paras...paras)->ScopeGuard<Func, Paras...>
{
return ScopeGuard<Func, Paras...>::MakeScopeGurad(func, paras...);
}
 
 
void FuncTest(int a, char b)
{
cout << "a:" << a << "   b:" << b << endl;
}
 
void FuncTest1()
{
cout << "FuncTest1" << endl;
}
 
int main(int argc, char* argv[])
{
auto sg1 = MakeScopeGurad(FuncTest, 10, 'd'); 
 
auto sg2 = MakeScopeGurad(FuncTest1);
 
auto sg3 = MakeScopeGurad([](string str){cout << str << endl; }, "C++11 lambda function");
 
tuple<> tp = std::make_tuple(); 
 
cout << "------------------------" << endl;
 
return 0;
}

下面是GCC编译链接和运行结果:
C++11版本的ScopeGuard

你可能感兴趣的:(scope)