
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:
and the relevant implementation:
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