
on Tue Jul 10 2007, Andrew Sutton <asutton-AT-cs.kent.edu> wrote:
Boost,
I've been working on parts of the Boost.Graph library as part of my Google Summer of Code project. Part of this has been implementing some new algorithms. Jeremy Siek (mentor) and I had briefly discussed using the new Boost.Parameter library instead of the older BGL Named Params solution for building the interfaces to these new algorithms. In fact, we had also talked about the possibility of migrating existing algorithms to use that style. So... after some initial experimentation, I've come up with some questions.
I've just finished reading most of the original reviews for Boost.Parameter library. They weren't that helpful.
Hmm, too bad.
1. It seems to me that functions with named parameters are limited to 5 parameters (both required and optional) - at least under GCC 4.1.2. Is this right?
That's just a default. Please see http://boost.org/libs/parameter/doc/html/reference.html#boost-parameter-max-...
2. I've run into the situation where parameters are truly optional - they don't specify default values, but optional components to an algorithm. What's the best way to implement this? How can I test (within a function) to determine if a parameter has been passed or not? I've hacked together an approach using a `not_given` struct. Is there something already like this in the library.
Sure; you could use boost::parameter::void_ as shown here: http://boost.org/libs/parameter/doc/html/index.html#class-template-skeleton
3. And the big kind of fuzzy question: Is there any general documented advice on building procedural interfaces with numerous default and replaceable arguments? These are all related to interface design and, if anybody responds, might generate some interesting discussion. Specific questions:
- At what point should an interface consider migrating to a named parameter solution instead of providing overloads?. For example, I could probably write many of my algorithms using overloads, but in order to be consistent with Boost.Graph (and other reasons) I'd like to use Boost.Parameter.
Well, don't forget the "deduced parameter" solution; that's even better than overloads. I guess I would think first about which interface will be more expressive for your users, and second about which is more expressive for you as a library builder. If the solution with overloads results in writing lots of code, especially if there's lots of repetetive boilerplate, that's another good sign you should be doing it differently.
- Which is better: executing behavior based on type or value parameters and when would each be appropriate? For example, should I pass a bool or enum flag to the function and make decisions at runtime, or should I define some policy- or tag-style structs and use template instantiation to determine behavior at compile time?
They serve different purposes. Do your users know which behavior they want at compile time? Also, note that one can always add a runtime choice wrapper on top of an interface that provides a compile time choice, but you can't go the other way.
- What's the best way to document these interfaces. Aside from Boost.Graph, I haven't yet seen any libraries, but those are documented for BGL named params. How do you describe the signature of a function that's declared as a macro?
Heh, heh: http://boost.org/libs/parameter/doc/html/index.html#documentation I would proably invent a hypothetical C++ declaration syntax (as though named/deduced paramters were built-in features), document that, and then document the functions in terms of it. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com The Astoria Seminar ==> http://www.astoriaseminar.com