이미 많은 좋은 답변이 있으므로 내 질문의 일부를 해결할 것입니다. 즉, OOP와 기능적 기능이 상호 배타적이지 않기 때문에 귀하의 질문에 전념합니다.
C ++ 11을 사용하는 경우 언어 / 표준 라이브러리에 내장 된 OOP와 시너지 효과를 제공하는 기능 프로그래밍 기능이 많이 있습니다. 물론 상사 나 동료가 TMP를 얼마나 잘받을 수 있을지 잘 모르겠지만 요점은 C ++과 같은 비 기능적 / OOP 언어로 이러한 기능을 여러 형태로 얻을 수 있다는 것입니다.
컴파일 시간 재귀와 함께 템플릿을 사용하는 것은 처음 3 점에 의존합니다.
이 템플릿 값은 변경할 수 없으며 (컴파일 타임 상수) 모든 반복은 재귀를 사용하여 수행되고 분기는 오버로드 확인 형식으로 패턴 일치를 사용하여 수행됩니다.
다른 점에 관해서는 부분 함수 적용을 사용 std::bind
하고 std::function
제공하며 함수 포인터는 언어에 내장되어 있습니다. 호출 가능한 객체는 기능적 객체 (부분 기능 응용 프로그램)입니다. 호출 가능한 객체는 객체를 정의하는 객체를 의미합니다 operator ()
.
게으른 평가와 순수한 기능은 조금 더 어려울 것입니다. 순수한 함수의 경우 값으로 만 캡처하는 람다 함수를 사용할 수 있지만 이는 바람직하지 않습니다.
마지막으로, 부분 함수 애플리케이션에서 컴파일 타임 재귀를 사용하는 예제가 있습니다. 다소 고안된 예이지만 위의 대부분의 요점을 보여줍니다. 주어진 튜플의 값을 주어진 함수에 재귀 적으로 바인딩하고 (호출 가능한) 함수 객체를 생성합니다.
#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;
}