Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2008-08-13 16:51:50


on Wed Aug 13 2008, "Stjepan Rajko" <stipe-AT-asu.edu> wrote:

> On Wed, Aug 13, 2008 at 11:41 AM, David Abrahams <dave_at_[hidden]> wrote:
>>
>> on Wed Aug 13 2008, "Peter Dimov" <pdimov-AT-pdimov.com> wrote:
>>
>>> Stjepan Rajko:
>>>
>>>> function_taking_both( label("hello") & size(1) );
>>>
>>> FWIW, I've been using this in a context where I needed "arbitrary"
>>> argument lists and it works. It has the advantage that the caller only
>>> needs to know about label and size, the eventual callee only needs to
>>> know about the arguments it recognizes and can ignore the rest, and
>>> the intermediate layers can pass everything downstream as-is without
>>> knowing about anything.
>>
>> Why is everyone hand-rolling the functionality we already have in
>> Boost.Parameter?
>>
>
> I can give you my reasons, at least :-)
>
> The major deciding factor was that I thought that Boost.Parameter-ized
> constructors required a base class to dispatch to. Looking back at
> the Boost.Parameters docs, here is what gave me that impression
> (section 2.3):
>
> "The lack of a "delegating constructor" feature in C++
> (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf)
> limits somewhat the quality of interface this library can provide for
> defining parameter-enabled constructors. The usual workaround for a
> lack of constructor delegation applies: one must factor the common
> logic into a base class."
>
> Note the word "must". Reading that entire section, I found nothing to
> change that impression.

You have to read on to the "Advanced Usage" section:
http://www.boost.org/doc/libs/1_35_0/libs/parameter/doc/html/index.html#more-argumentpacks
to see that you can build ArgumentPacks directly. However, although
that may be simpler from the library implementor's point-of-view, it
imposes several important limitations on your clients. First and
foremost is that positional arguments become much harder for them to
use. I wrote the tutorial with the assumption that the reader was
primarily interested in providing the best possible interface to his
clients.

> Another reason is that I found the following syntax intimidating:
> BOOST_PARAMETER_FUNCTION(
> (void), // 1. parenthesized return type
> depth_first_search, // 2. name of the function template
>
> tag, // 3. namespace of tag types
>
> (required (graph, *) ) // 4. one required parameter, and
>
> (optional // four optional parameters, with defaults
> (visitor, *, boost::dfs_visitor<>())
> (root_vertex, *, *vertices(graph).first)
> (index_map, *, get(boost::vertex_index,graph))
> (in_out(color_map), *,
> default_color_map(num_vertices(graph), index_map) )
> )
> )
>
> It looks like a very powerful syntax, but also something that would be
> easy to trip over (remembering the order of macro parameters, for
> example).

Actually that's very easy. With the exception of "tag", the order
corresponds to exactly what you'd write if named parameters were
supported in the language:

  template <class Graph, class Visitor, class IndexMap, class ColorMap>
  void
  depth_first_search
      // tag
  (
      // required
      Graph const& graph,

      // optional
      Visitor const& visitor = boost::dfs_visitor<>(),
      typename graph_traits<Graph>::vertex_descriptor root_vertex = *vertices(graph).first
      IndexMap const& index_map = get(boost::vertex_index, graph),
      ColorMap& c = default_color_map(num_vertices(graph), index_map)
  );

> Perhaps it is easy to just write what the macro would
> expand to by hand,

Of course it isn't; if it were easy we wouldn't have felt compelled to
provide a macro! What the macro does works so well for the library
author *and* his clients that we absolutely had to provide it. The
macro handles the forwarding problem, uses SFINAE to ensure the function
template doesn't match invalid arguments, and unwinds the ArgumentPack
so that both the types and values of the parameters are conveniently
available *by name* in the function body. It allows arguments to be
passed both positionally and by name (not to mention support for deduced
parameters that don't need to be named).

> but after deciding not to use the library because of the first reason
> I listed, I didn't really feel motivated to look into it further.
>
> Finally, I was concerned about the impact on compile time, which I've
> seen mentioned on the list a few times. Whether what I have now is
> any faster is yet to be tested.

I'd be interested in hearing the results.

-- 
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