Boost logo

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