|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2008-08-13 11:43:47
on Wed Aug 13 2008, "Stjepan Rajko" <stipe-AT-asu.edu> wrote:
> Hello,
>
> I just realized that named parameters can be implemented rather nicely
> using fusion maps (I'm not sure whether this has been explored
> before).
Yes, we looked into it. It didn't work out for various reasons.
> I threw together an implementation for two particular
> parameters/names, but the method could be easily generalized. Here
> are examples of functions taking parameter packs (label is a string,
> and size is a guigl::size_type which is a gil::point2 type) (...and
> don't worry about what guigl is):
>
> using namespace guigl::parameter;
>
> const std::string &function_taking_label(const pack<field::label>::type &args)
> {
> return args.label();
> }
>
> const guigl::size_type &function_taking_size(const
> pack<field::size>::type &args)
> {
> return args.size();
> }
>
> const guigl::size_type &function_taking_both(const pack<field::label,
> field::size>::type &args)
> {
> return args.size();
> }
>
> Now you can do things like:
> function_taking_label(label("hello"));
>
> const guigl::size_type size_one(1,1);
> function_taking_size(size(size_one));
>
> // parameters can be passed in any order
> function_taking_both(label("hello").size(size_one));
> function_taking_both(size(size_one).label("hello"));
Yes, but this chaining interface is the same one used by the old
Boost.Graph named parameter interface (which incidentally I suggested),
and has a nasty coupling problem that we explicitly wanted to avoid: all
the possible parameter names need to be known in one place, and must be
available to all the functions that may use said parameters. I suggest
going back in the message archives to look at the original review
commentary for Boost.Parameter if you want to understand our design
rationale.
Hmm, I suppose we really ought to document that.
> // size has a default value
> function_taking_both(label("hello"));
>
> // extraneous parameters will be ignored
> function_taking_label(label("hello").size(size_one));
>
> // empty parameter pack can be used for no parameters (all default values)
> function_taking_size(empty());
>
>
>
> Here is the full test code:
>
> http://pastebin.com/f6b128a4b
>
> and the relevant implementation:
>
> http://pastebin.com/f584c7967
>
>
> Compared to Boost.Parameter, I have a hunch that the Fusion approach
> would be faster to compile (haven't tested that though),
Why don't you do some testing if you think so? Don't forget to make sure
your library supports all the same features as Boost.Parameter. Making
it pass the Boost.Parameter test suite would be a good start.
> and is a little bit less convoluted (esp. for certain cases like
> constructors using named parameters).
Boost.Parameter supports an equivalent approach to the one you're using
here, if you want to use it, which avoids the need for a base class to
dispatch to. The problem is that, like your approach, the syntax is
slightly unnatural:
SomeClass((label="hello", size=size_one))
In other words, you can explicitly build an ArgumentPack and pass that.
> I've never used Boost.Parameter so I'm not sure what other comparisons
> might apply.
Then isn't it a bit early to be talking about the superiority of this
approach?
-- Dave Abrahams BoostPro Computing http://www.boostpro.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk