[모던C++입문] 3.8 펑터
- 📕 Book/모던C++입문
- 2021. 7. 14.
3.8 펑터
- 펑터(Functor), 함수 개체(Functional Object)
- 함수처럼 호출할수 있는 연산자를 제공하는 클래스
//함수포인터를 사용한 유한 차분
double fin_diff(double f(double), double x, double h)
{
return (f(x + h) - f(x)) / h;
}
double sin_plus_cos(double x)
{
return sin(x) + cos(x);
}
int main()
{
cout << fin_diff(sin_plus_cos, 1., 0.001) << endl;
cout << fin_diff(sin_plus_cos, 0., 0.001) << endl;
return 0;
}
//함수 개체
struct sc_f
{
//sin_plus_cos 함수를 펑터로 구현
double operator() (double x) const
{
return sin(x) + cos(x);
}
}
펑터 합성하기
template<typename F, typename T>
class derivative //1계 도함수
{
public:
derivative(const F& f. const T& h) : f(f), h(h) {}
T operator()(const T& x) const
{
return ( f(x+h) - f(x) ) / h;
}
private:
const F& f;
T h;
}
template<typename F, typename T>
class second_derivative //2계 도함수
{
public:
second_derivative(const F& f, const T& h) : h(h), fp(f, h) {}
T operator()(const T& x) const
{
return ( fp(x+h) / fp(x) ) / h;
}
private:
T h;
derivative<F, T> fp;
}
재귀
- 앞서 해본 1,2계 도함수를 구하는 방법을 찾았고, 이번엔 n계 도함수를 구하기 위해 (n-1)계 도함수를 구하는 방법으로 재귀적 구현을 통해 탐색해보자.
template<typename F, typename T, usinged N>
class nth_derivative
{
using prev_derivative = nth_derivative<F, T, N-1>;
public:
nth_derivative(const F& f, const T& h) : h(h), fp(f, h) {}
T operator()(const T& x) const
{
return ( fp(x+h) - fp(x) ) / h;
}
private:
T h;
prev_derivative fp;
}
- 그리고 1계도함수에 도달했을때 무한 루프에 빠지지 않도록 중단을 해주어야한다.
- 다음과 같은 특수화로 종료하자.
template<fypname F, typename T>
class nth_derivative<F,T,1>
{
public:
nth_derivative(const F& f, const T& h) : f(f), h(h) {}
T operator()(const T& x) const
{
return ( f(x+h) - f(x) ) / h;
}
private:
const F& f;
T h;
}
제네릭 축소
template<typename Iter, typename T, typename BinaryFunction>
T accumulate(Iter it, Iter end, T init, BinaryFunction op)
{
for(; it != end; ++it)
init = op(init, *it);
return init;
}
//매개 변수화된 펑터 구현
template<typename T>
struct add
{
T operator()(const T& x, const T& y) const {return x + y;}
};
//operator()를 매개변수화
struct times
{
template<typename T>
T operator()(const T& x, const T& y) const { return x * y; }
};
double v = {7.0, 8.0, 11.0 };
double s = accumulate(v.begin(), v.end(), add<double>{});
double p = accumulate(v.begin(), v.end(), times{});
반응형