As amply illustrated in chapter ref(GENERIC) function objects play an
important role with generic algorithms. Like generic algorithms themselves,
function objects can be generically defined as members of class templates. If
the function call operators (tt(operator())) of such classes define parameters
then the types of those parameters may also be abstracted by defining the
function call operators themselves as member templates.  Example:
        verb(    template <typename Class>
    class Filter
    {
        Class obj;
        public:
            template <typename Param>
            Param operator()(Param const &param) const
            {
                return obj(param);
            }
    };)

The template class tt(Filter) is a wrapper around tt(Class), filtering
tt(Class)'s function call operator through its own function call operator. In
the above example the return value of tt(Class)'s function call operator is
simply passed on, but any other manipulation is of course also possible.

    A type that is specified as tt(Filter)'s template type argument may of
course have multiple function call operators:
        verb(    struct Math
    {
        int operator()(int x);
        double operator()(double x);
    };)

tt(Math) objects can now be filtered using tt(Filter<Math> fm) using
tt(Math)'s first or second function call operator, depending on the actual
argument type. With tt(fm(5)) the tt(int)-version is used, with tt(fm(12.5))
the tt(double)-version is used.

    However, this scheme doesn't work if the function call operators have
different return and argument types. Because of this the following class
tt(Convert) cannot be used with tt(Filter):
        verb(    struct Convert
    {
        double operator()(int x);           // int-to-double
        std::string operator()(double x);   // double-to-string
    };)

This problem can be tackled successfully by the class template
 hi(return type: via result_of)hi(result_of)
 tt(std::result_of<Functor(Typelist)>). Before using tt(std::result_of) the
header file tthi(functional) must be included.

The tt(result_of) class template offers a using declaration (tt(type)),
representing the type that is returned by tt(Functor<TypeList>). It can be
used as follows to improve the implementation of tt(Filter):
        verb(    template <typename Class>
    class Filter
    {
        Class obj;
        public:
            template <typename Arg>
                typename std::result_of<Class(Arg)>::type
                operator()(Arg const &arg) const
                {
                    return obj(arg);
                }
    };)

Using this definition, tt(Filter<Convert> fc) can be constructed. Now
tt(fc(5)) returns a tt(double), while tt(fc(4.5)) returns a
tt(std::string).

The class tt(Convert) must define the relationships between its function call
operators and their return types. Predefined function objects (like those in
the standard template library) already do so, but self-defined function
objects must do this explicitly.

If a function object class defines only one function call operator it can
specify its return type through a using-declaration. If the above class
tt(Convert) would only define the first of its two function call operators
then the using declaration (in the class's tt(public) section) should be:
        verb(    using type = double;)

If multiple function call operators are defined, each with its own signature
and return type, then the association between signature and return type is set
up as follows (all in the class's tt(public) section):
    itemization(
    it() define a generic tt(struct result) like this:
        verb(template <typename Signature>
struct result;)

it() For each function call signature define a em(specialization) of
tt(struct result). tt(Convert)'s first function call operator gives rise to:
        verb(template <typename Class>
struct result<Class(int)>
{
    using type = double;
};)

and tt(Convert)'s second function call operator to:
        verb(template <typename Class>
struct result<Class(double)>
{
    using type = std::string;
};)

it() In cases where function call operators have multiple arguments the
specifications should again provide for the correct signatures. A function
call operator called with an tt(int) and a tt(double), returning a tt(size_t)
gets:
        verb(template <typename Class>
struct result<Class(int, double)>
{
    using type = size_t;
};)

)
