概念
百度定义:
闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)
闭包,即有状态的函数,更直接的来说,便是一个类
一个函数,带上“状态”,便是闭包,按如下理解
- 闭包有属于自己的变量(非static)
- 变量的值(状态),在创建时绑定
- 调用闭包时,可访问这些变量
故总结如下:
函数是代码,状态是一组变量,将代码和一组变量捆绑,即是闭包
闭包的实现
重载operator()
class MyFunctor
{public:
MyFunctor(int tmp) : round(tmp) {}
int operator()(int tmp) { return tmp + round; }private:
int round;
};
int main()
{
int round = 2;
MyFunctor f(round);//调用构造函数
cout << "result = " << f(1) << endl; //operator()(int tmp)
return 0;
}
lambda表达式
c++11提供的lambda是个很不错的语法糖
int round = 2;
auto f = [=](int f) -> int { return f + round; } ;
cout << "result = " << f(1) << endl;
std::bind
更为强大的语法糖,将需要手写多行的代码闭包,浓缩到一行之中
int func(int a,int b,int c){
.....
}
using namespace std::placeholders;
auto f=std::bind(func,_1,2,3);
libco_closure
功能如下:
co_ref(name,...)
:定义一个包含所有参数引用类的类,并构造一个对象
co_func(name,...)
:定义一个包含所有参数引用类的类,并继承stCoClosure_t
,以重载exec()
#ifndef __CO_CLOSURE_H__
#define __CO_CLOSURE_H__
struct stCoClosure_t
{
public:
virtual void exec() = 0;
virtual ~stCoClosure_t(){}
};
//1.base
//-- 1.1 comac_argc
/**参数推导
* comac_argc(A,B,C)
* comac_get_args_cnt(0,A,B,C,7,6,5,4,3,2,1,0)
* comac_arg_n(0,A,B,C,7,6,5,4,3,...)
* | 推导出参数数量为3个
* 前缀##有一个特殊约定,即当##arg前面是逗号(,)时,如果arg为空,则##之前的逗号(,)
* comac_argc()
* comac_arg_n(0,7,6,5,4,3,2,1,0) -->N=0
*
* __VA_ARGS__:代表全部可变参数,相当于宏替换
*/
#define comac_get_args_cnt( ... ) comac_arg_n( __VA_ARGS__ )
#define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,N,...) N
#define comac_args_seqs() 7,6,5,4,3,2,1,0
#define comac_join_1( x,y ) x##y
#define comac_argc( ... ) comac_get_args_cnt( 0,##__VA_ARGS__,comac_args_seqs() )
#define comac_join( x,y) comac_join_1( x,y )
//-- 1.2 repeat
/**对闭包传入的参数类型声明
* 根据不同的参数数量调用不同的函数,其实是一个递归的过程
*/
#define repeat_0( fun,a,... )
#define repeat_1( fun,a,... ) fun( 1,a,__VA_ARGS__ ) repeat_0( fun,__VA_ARGS__ )
#define repeat_2( fun,a,... ) fun( 2,a,__VA_ARGS__ ) repeat_1( fun,__VA_ARGS__ )
#define repeat_3( fun,a,... ) fun( 3,a,__VA_ARGS__ ) repeat_2( fun,__VA_ARGS__ )
#define repeat_4( fun,a,... ) fun( 4,a,__VA_ARGS__ ) repeat_3( fun,__VA_ARGS__ )
#define repeat_5( fun,a,... ) fun( 5,a,__VA_ARGS__ ) repeat_4( fun,__VA_ARGS__ )
#define repeat_6( fun,a,... ) fun( 6,a,__VA_ARGS__ ) repeat_5( fun,__VA_ARGS__ )
#define repeat( n,fun,... ) comac_join( repeat_,n )( fun,__VA_ARGS__)
//2.implement
/**根据不同的参数数量调用不同的函数,其实是一个递归的过程
* string str="hello world"
* decl_typeof(i,str) -> typedef decltype(str) typeof_str; 获取类型
* impl_typeof(i,str) -> typeof_str & str; 定义引用
* impl_typeof(i,str) -> typeof_str str; 申请变量
* con_param_typeof(i,str) -> typeof_str & strr, 生成函数参数
* param_init_typeof(i,str) -> str(strr), 生成初始化列表
*/
#if __cplusplus <= 199711L
#define decl_typeof( i,a,... ) typedef typeof( a ) typeof_##a;
#else
#define decl_typeof( i,a,... ) typedef decltype( a ) typeof_##a;
#endif
#define impl_typeof( i,a,... ) typeof_##a & a;
#define impl_typeof_cpy( i,a,... ) typeof_##a a;
#define con_param_typeof( i,a,... ) typeof_##a & a##r,
#define param_init_typeof( i,a,... ) a(a##r),
//2.1 reference
/**
* int number=1024;
* string str="hello world"
* co_ref(ref,number,str)-->
* --------------------------------------------------------------分界线
* typedef typeof(number) typeof_number;
* typedef typeof(str) typeof_str;
*
* class type_ref
* {
* public:
* typeof_number & number;
* typeof_str & str;
* int _member_cnt;
* type_ref(typeof_number & numberr,typeof_str & strr):
* number(numberr),str(strr),_member_cnt(2)
* {}
* }ref(number,str);
*
* 一个宏函数再推导后,形成一个包含所有参数的类;
* 且按外部参数生成了一个对应的对象
*/
#define co_ref( name,... )\
repeat( comac_argc(__VA_ARGS__) ,decl_typeof,__VA_ARGS__ )\
class type_##name\
{\
public:\
repeat( comac_argc(__VA_ARGS__) ,impl_typeof,__VA_ARGS__ )\
int _member_cnt;\
type_##name( \
repeat( comac_argc(__VA_ARGS__),con_param_typeof,__VA_ARGS__ ) ... ): \
repeat( comac_argc(__VA_ARGS__),param_init_typeof,__VA_ARGS__ ) _member_cnt(comac_argc(__VA_ARGS__)) \
{}\
} name( __VA_ARGS__ ) ;
//2.2 function
/** 生成包含所有参数引用的类并重载 stCoClosure_t 的exec
* int number=1024;
* string str="hello world"
* co_ref(ref,number,str)
*
* co_func(f,ref)
* {
* printf("hello world");
* }
* --------------------------------------------------------------分界线
* typedef typeof(number) typeof_number;
* typedef typeof(str) typeof_str;
*
* class type_ref
* {
* public:
* typeof_number & number;
* typeof_str & str;
* int _member_cnt;
* type_ref(typeof_number & numberr,typeof_str & strr):
* number(numberr),str(strr),_member_cnt(2)
* {}
* }ref(number,str);
*
*
*typedef typeof(ref) typeof_ref;
*class f : public stCoClosure_t
*{
*public:
* typeof_ref ref;
* int _member_cnt;
*public:
* f(typeof_ref & refr, ...) : ref(refr), _member_cnt(1)
* {
* }
* void exec()
* {
* printf("hello, world!\n"); <<---------------------- exec为重点修改对象!!
* }
*};
*
*
*/
#define co_func(name,...)\
repeat( comac_argc(__VA_ARGS__) ,decl_typeof,__VA_ARGS__ )\
class name:public stCoClosure_t\
{\
public:\
repeat( comac_argc(__VA_ARGS__) ,impl_typeof_cpy,__VA_ARGS__ )\
int _member_cnt;\
public:\
name( repeat( comac_argc(__VA_ARGS__),con_param_typeof,__VA_ARGS__ ) ... ): \
repeat( comac_argc(__VA_ARGS__),param_init_typeof,__VA_ARGS__ ) _member_cnt(comac_argc(__VA_ARGS__))\
{}\
void exec()
#define co_func_end }
#endif