C++实现的一个可以写递归lambda的Y函数
最近学习C++11的variadictemplateargument,终于可以摆脱用fpmacro模板来复制一大堆代码的做法了,好开心。这个例子的main函数用lambda写了一个斐波那契数列的递归计算函数。跟以往不同的是,在Y函数的帮助下,这个lambda表达是可以成功看到自己,然后递归调用。当然这仍然需要用普通的C++递归来实现,并不是λ-calculus那个高大上的YCombinator。
#include<functional>
#include<memory>
#include<iostream>
#include<string>
usingnamespacestd;
template<typenameTResult,typename...TArgs>
classYBuilder
{
private:
function<TResult(function<TResult(TArgs...)>,TArgs...)>partialLambda;
public:
YBuilder(function<TResult(function<TResult(TArgs...)>,TArgs...)>_partialLambda)
:partialLambda(_partialLambda)
{
}
TResultoperator()(TArgs...args)const
{
returnpartialLambda(
[this](TArgs...args)
{
returnthis->operator()(args...);
},args...);
}
};
template<typenameTMethod>
structPartialLambdaTypeRetriver
{
typedefvoidFunctionType;
typedefvoidLambdaType;
typedefvoidYBuilderType;
};
template<typenameTClass,typenameTResult,typename...TArgs>
structPartialLambdaTypeRetriver<TResult(__thiscallTClass::*)(function<TResult(TArgs...)>,TArgs...)>
{
typedefTResultFunctionType(TArgs...);
typedefTResultLambdaType(function<TResult(TArgs...)>,TArgs...);
typedefYBuilder<TResult,TArgs...>YBuilderType;
};
template<typenameTClass,typenameTResult,typename...TArgs>
structPartialLambdaTypeRetriver<TResult(__thiscallTClass::*)(function<TResult(TArgs...)>,TArgs...)const>
{
typedefTResultFunctionType(TArgs...);
typedefTResultLambdaType(function<TResult(TArgs...)>,TArgs...);
typedefYBuilder<TResult,TArgs...>YBuilderType;
};
template<typenameTLambda>
function<typenamePartialLambdaTypeRetriver<decltype(&TLambda::operator())>::FunctionType>Y(TLambdapartialLambda)
{
returntypenamePartialLambdaTypeRetriver<decltype(&TLambda::operator())>::YBuilderType(partialLambda);
}
int_tmain(intargc,_TCHAR*argv[])
{
autofib=Y([](function<int(int)>self,intindex)
{
returnindex<2
?1
:self(index-1)+self(index-2);
});
for(inti=0;i<10;i++)
{
cout<<fib(i)<<"";
}
cout<<endl;
}