已经有很多好的答案,因此我将解决您的部分问题;也就是说,我谨代表您提出问题的前提,因为OOP和功能部件不是互斥的。
如果使用C ++ 11,则语言/标准库中内置了许多此类功能编程功能,这些功能可以与OOP很好地协同(很好)。当然,我不确定您的老板或同事对TMP的接受程度如何,但是重点是您可以以某种形式或以其他非功能性/ OOP语言(例如C ++)获得许多这些功能。
使用具有编译时间递归的模板取决于您的前三点,
由于模板值是不可变的(编译时常量),因此任何迭代都使用递归完成,而分支则使用(或多或少)模式匹配来完成,并以过载解析的形式进行。
至于其他要点,使用std::bind
和std::function
给您提供部分函数应用程序,并且函数指针是该语言的内置函数。可调用对象是功能对象(以及部分功能应用程序)。请注意,所谓可调用对象,是指定义其的对象operator ()
。
惰性求值和纯函数会有点困难;对于纯函数,可以使用仅按值捕获的lambda函数,但这是不理想的。
最后,这是在部分函数应用程序中使用编译时递归的示例。这是一个有些人为的例子,但它说明了上面的大多数观点。它将递归地将给定元组中的值绑定到给定函数,并生成(可调用的)函数对象
#include <iostream>
#include <functional>
//holds a compile-time index sequence
template<std::size_t ... >
struct index_seq
{};
//builds the index_seq<...> struct with the indices (boils down to compile-time indexing)
template<std::size_t N, std::size_t ... Seq>
struct gen_indices
: gen_indices<N-1, N-1, Seq ... >
{};
template<std::size_t ... Seq>
struct gen_indices<0, Seq ... >
{
typedef index_seq<Seq ... > type;
};
template <typename RType>
struct bind_to_fcn
{
template <class Fcn, class ... Args>
std::function<RType()> fcn_bind(Fcn fcn, std::tuple<Args...> params)
{
return bindFunc(typename gen_indices<sizeof...(Args)>::type(), fcn, params);
}
template<std::size_t ... Seq, class Fcn, class ... Args>
std::function<RType()> bindFunc(index_seq<Seq...>, Fcn fcn, std::tuple<Args...> params)
{
return std::bind(fcn, std::get<Seq>(params) ...);
}
};
//some arbitrary testing function to use
double foo(int x, float y, double z)
{
return x + y + z;
}
int main(void)
{
//some tuple of parameters to use in the function call
std::tuple<int, float, double> t = std::make_tuple(1, 2.04, 0.1);
typedef double(*SumFcn)(int,float,double);
bind_to_fcn<double> binder;
auto other_fcn_obj = binder.fcn_bind<SumFcn>(foo, t);
std::cout << other_fcn_obj() << std::endl;
}