|
Boost : |
From: Joel de Guzman (djowel_at_[hidden])
Date: 2003-01-23 23:14:07
----- Original Message -----
From: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>
> My current understanding (which, admittedly, is not backed up by a
> real-world experience) is that if you care about higher-orderness of your
> generic algorithms, a preferred implementation construct for those
> algorithms is not a function template, but a static _function object_ (a
> technique used in FC++):
>
> struct my_function_
> {
> template< typename U >
> void operator()(std::string const& text, U)
> {
> // ...
> }
>
> } my_function; // here!
>
>
> For ordinary uses, the above will act just like a plain function template
> (minus ADL/explicit template arguments specification):
>
> my_function("text", int());
>
> and it will also allow one to do something like this:
>
> std::string text("text");
> mpl::for_each< my_types >(boost::bind<void>(my_function, text, _1));
This technique is adopted by Phoenix. With this, you can even do
(as suggested by Joel Young):
- \ \
double - /\ f . /\ x. f(f x)
- / \ / \
struct square_ {
template <typename X>
struct result { typedef X type; };
template <typename X>
X operator()(X x)
{
return x * x;
}
};
function<square_> square;
template <typename F>
struct ffx {
template <typename X>
struct result { typedef X type; };
ffx(F f_) : f(f_) {}
template <typename X>
X operator()(X x)
{
return f(f(x));
}
F f;
};
template <typename F>
function<ffx<F> >
doub(function<F> f)
{
return function<ffx<F> >(f.op);
}
int
main()
{
cout << doub(square)(5.0)() << endl;
cout << doub(doub(square))(5.0)() << endl;
cout << doub(doub(doub(square)))(5.0)() << endl;
return 0;
}
Cheers,
Joel de Guzman
joel_at_[hidden]
http://www.boost-consulting.com
PS> Jaakko and I are working on the LL/Phoenix merger.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk