|
Boost : |
From: Daniel Wallin (dalwan01_at_[hidden])
Date: 2003-10-06 07:36:03
At 01:54 2003-10-06, David Abrahams wrote:
>Daniel Wallin <dalwan01_at_[hidden]> writes:
>
> >>I thought I'd open it up for suggestions. Thoughts, anyone?
> >
> > I got two ideas on how to reduce the code required for a function. I'm
> > attaching a modified version of your code which demonstrates the
> > two ideas on your example functions.
>
>Daniel,
>
>as usual you are full of good ideas ;-)
>
>The one which makes f into a function object is appealing to me in
>part because it *doesn't* support Koenig lookup. Generalized function
>templates are dangerous in the presence of ADL.
>
>Is it possible to combine the approaches to reduce the amount of code
>in the function object implementation?
Do you mean in the "named_param_fun" base? In that case yes, it could be
written like:
R operator()() const
{
return (*this)(nil());
}
template<class A0>
R operator()(const A0& a0) const
{
return (*this)(a0, nil());
}
template<class A0, class A1>
R operator()(const A1& a1, const A2& a2) const
{
return static_cast<const Derived&>(*this).call(
(key0(a0), key1(a1), key2(a2)));
}
etc, and terminate at some predetermined arity. Another thing I was thinking
about is that the keyword types could be defined inside the function object
type, so that the actual function implementation could be written like:
struct f_impl : named_param_fun<f_impl, int>
{
template<class Params>
int call(const Params& p) const
{
std::cout << "-------- f --------" << std::endl;
std::cout << "name = " << p.value(name).get("unnamed") << std::endl;
std::cout << "value = " << p.value(value).get(666.222) << std::endl;
std::cout << "index = " << p.value(index).get(999) << std::endl;
return 1;
}
} f;
f_impl::_1 name;
f_impl::_2 value;
f_impl::_3 index;
That would bind the keyword types to the function though, and I'm not sure
that's
desirable. It's also really easy to place the keywords as members in the
function
object:
struct f_impl : named_param_fun<f_impl, int>
{
_1 name;
_2 value;
_3 index;
template<class Params>
int call(const Params& p) const
{
std::cout << "-------- f --------" << std::endl;
std::cout << "name = " << p.value(name).get("unnamed") << std::endl;
std::cout << "value = " << p.value(value).get(666.222) << std::endl;
std::cout << "index = " << p.value(index).get(999) << std::endl;
return 1;
}
} f;
f(f.name = "foo");
Which is kind of cool, but perhaps too verbose.
I guess you could always use some exotic operator overloading to shorten
the getter functions.
p.value(name).get("unnamed") -> p[name | "unnamed"]
Or something like that, but I'm not sure I think the first version is too
verbose. :)
--- Daniel Wallin
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk