/* 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 FO1, typename FO2>
class Composer {
private:
FO1 fo1; // first/inner function object to call
FO2 fo2; // second/outer function object to call
public:
// constructor: initialize function objects
Composer (FO1 f1, FO2 f2)
: fo1(f1), fo2(f2) {
}
// ''function call'': nested call of function objects
double operator() (double v) {
return fo2(fo1(v));
}
};
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 << Composer<Abs,Sine>(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(Composer<Abs, Sine>(Abs(), Sine()));
std::cout << '\n';
// print abs(sin()) of some values
print_values(Composer<Sine, Abs>(Sine(), Abs()));
}
0.479426
f(-0.2) = 0.2
f(-0.1) = 0.1
f(0) = 0
f(0.1) = 0.1
f(0.2) = 0.2
f(-0.2) = -0.198669
f(-0.1) = -0.0998334
f(0) = 0
f(0.1) = 0.0998334
f(0.2) = 0.198669
f(-0.2) = 0.198669
f(-0.1) = 0.0998334
f(0) = 0
f(0.1) = 0.0998334
f(0.2) = 0.198669
f(-0.2) = 0.198669
f(-0.1) = 0.0998334
f(0) = 0
f(0.1) = 0.0998334
f(0.2) = 0.198669