/*
 *  Function Objects
 *
 */

template<class T> class Sum {
    T res;
public:
    Sum(T i = 0) : res(i) { }           // initialize
    void operator()(T x) { res += x; }  // accumulate
    T result() const { return res; }    // return sum
};      


/*
 *  Usage of a function objects
 *
 */

void f(list<double>& ld)
{
    Sum<double> s;
    s = for_each(ld.begin(),ld.end(),s);    // invoke s() for each element of ld
    cout << "the sum is " << s.result() << '\n';
}


template <class Arg, class Res> struct unary_function {
        typedef Arg argument_type;
        typedef Res result_type;
};

template <class Arg, class Arg2, class Res> struct binary_function {
        typedef Arg first_argument_type;
        typedef Arg2 second_argument_type;
        typedef Res result_type;
};



template <class T> struct logical_not : public unary_function<T,bool> {
        bool operator()(const T& x) const { return !x; }
};

template <class T> struct less : public binary_function<T,T,bool> {
        bool operator()(const T& x, const T& y) const { return x<y; }
};