/* The following code example is taken from the book
* "C++ Templates - The Complete Guide"
* by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002
*
* (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <iostream>
#include <cmath>
#include <cstdlib>
class Abs {
public:
// ''function call'':
double operator() (double v) const {
return std::abs(v);
}
};
class Sine {
public:
// ''function call'':
double operator() (double a) const {
return std::sin(a);
}
};
template <typename C, int N>
class BaseMem : public C {
public:
BaseMem(C& c) : C(c) { }
BaseMem(C const& c) : C(c) { }
};
template <typename FO1, typename FO2>
class Composer : private BaseMem<FO1,1>,
private BaseMem<FO2,2> {
public:
// constructor: initialize function objects
Composer(FO1 f1, FO2 f2)
: BaseMem<FO1,1>(f1), BaseMem<FO2,2>(f2) {
}
// ''function call'': nested call of function objects
double operator() (double v) {
return BaseMem<FO2,2>::operator()
(BaseMem<FO1,1>::operator()(v));
}
};
template <typename FO1, typename FO2>
inline
Composer<FO1,FO2> compose (FO1 f1, FO2 f2) {
return Composer<FO1,FO2> (f1, f2);
}
template<typename FO>
void print_values (FO fo)
{
for (int i=-2; i<3; ++i) {
std::cout << "f(" << i*0.1
<< ") = " << fo(i*0.1)
<< "\n";
}
}
int main()
{
// print sin(abs(-0.5))
std::cout << compose(Abs(),Sine())(0.5) << "\n\n";
// print abs() of some values
print_values(Abs());
std::cout << '\n';
// print sin() of some values
print_values(Sine());
std::cout << '\n';
// print sin(abs()) of some values
print_values(compose(Abs(),Sine()));
std::cout << '\n';
// print abs(sin()) of some values
print_values(compose(Sine(),Abs()));
std::cout << '\n';
// print sin(sin()) of some values
print_values(compose(Sine(),Sine()));
}
|