|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2003-10-06 08:23:31
Daniel Wallin <dalwan01_at_[hidden]> writes:
> 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)));
> }
Nice.
> etc, and terminate at some predetermined arity.
Which happens anyway.
> 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.
IMO it's not.
> 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.
Yeah.
> 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. :)
Well, I think your syntax suggestion is beautiful! However, I think
there may be some inmplementation difficulty. Can you implement it?
There was a reason I went with the two-call .value(x).get(y) syntax.
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk