From: Richard Peters (R.A.Peters_at_[hidden])
Date: 2001-12-06 06:22:30


From: <nbecker_at_[hidden]>
> While you're at it, I'd like to see constant. Something like:
>

What about a more general case: a constant generator, and a unary_function
that ignores the first value but returns the generator instead? Combined
they provide the functionality of your Constant, and they are also usable as
stand-alone functors. And maybe the generator class that behaves similar to
unary_function/binary_function (doesn't it already exist?)

template<class Result>
struct generator {
    typedef Result result_type;
};

template<class Arg, class Result, class Generator>
struct unary_ignore: public unary_function<Arg, Result> {
    unary_ignore() {}
    unary_ignore(Generator thegenerator):
        generator(thegenerator) {}
    Result operator()(typename call_traits<Arg>::param_type)
    {
        return Generator();
    };
private:
    Generator generator;
};

template<class Result>
struct constant: public generator<Result> {
    constant(Result thevalue):
        value(thevalue) {}
    Result operator()()
    {
        return value;
    }
private:
    const Result value;
};

and the same for the binary_function, you could ignore one of the two
parameters:

template<class Arg1, class Arg2, class Result, class UnaryFunction>
struct binary_ignore1st: public binary_function<Arg1, Arg2, Result> {
    binary_ignore1st() {}
    binary_ignore1st(UnaryFunction thefunction):
        unaryfunction(thefunction) {}
    Result operator()(typename call_traits<Arg1>::param_type,
                      typename call_traits<Arg2>::param_type y)
    {
        return unaryfunction(y);
    }
private:
    UnaryFunction unaryfunction;
};

template<class Arg1, class Arg2, class Result, class UnaryFunction>
struct binary_ignore2nd: public binary_function<Arg1, Arg2, Result> {
    binary_ignore2st() {}
    binary_ignore2st(UnaryFunction thefunction):
        unaryfunction(thefunction) {}
    Result operator()(typename call_traits<Arg1>::param_type x,
                      typename call_traits<Arg2>::param_type)
    {
        return unaryfunction(x);
    }
private:
    UnaryFunction unaryfunction;
};

Maybe the templates could be changed to something like:

template<class Generator, class Arg, class Result = typename
Generator::result_type>
struct unary_ignore: public unary_function<Arg, Result>

template<class UnaryFunction, class Arg1, class Arg2 = typename
UnaryFunction::argument_type,
    class Result = typename UnaryFunction::result_type>
struct binary_ignore1st: public binary_function<Arg1, Arg2, Result>

but on this one, it doesn't look as sweet:

template<class UnaryFunction, class Arg2, class Arg1 = typename
UnaryFunction::argument_type,
    class Result = typename UnaryFunction::result_type>
struct binary_ignore2nd: public binary_function<Arg1, Arg2, Result>

A third option would be not to give a choice a and always use the default:

template<class Generator, class Arg>
struct unary_ignore: public unary_function<Arg, typename
Generator::result_type>

template<class UnaryFunction, class Arg1>
struct binary_ignore1st: public binary_function<Arg1, typename
UnaryFunction::argument_type, typename
    UnaryFunction::result_type>

template<class UnaryFunction, class Arg2>
struct binary_ignore2nd: public binary_function<typename
UnaryFunction::argument_type, Arg2, typename
    UnaryFunction::result_type>

I'm not an expert, so I don't really know what variant would be the best.
What do you think? Does it make any sense?

Best Regards,
Richard Peters