Boost logo

Boost :

From: Richard Smith (richard_at_[hidden])
Date: 2006-11-18 10:14:34


Tobias Schwinger wrote:

> Further: none of the reviewers (except Doug Gregor, who
> was talking about the issue in the very specific context
> of merger with another library) did answer the following
> question:
>
> What's wrong with the tag types (other than personal
> taste) in the first place?

Having just read your other email, I think I now better
understand why you want tags -- and why you don't want to go
the traits route that I suggested.

What I don't like about the current interface is that it
seems to use an odd mixture of traits and tags. Let me try
to explain.

The library is supplying an interface to manipulate function
types (and function pointer, function reference and member
function pointer types). The two most obvious parts of a
function type are the return type and the parameter types.
These are queried via traits:

  result_type< Fn >::type
  mpl::at_c< parameter_types< Fn >, N >::type

However, on top of this, there are other aspects: calling
convention and variadic-ness (both of which are probably
relatively rarely required), and cv-quals for member
functions (which might be more frequently needed). These
are all handled by the tags mechanism.

  is_callable_builtin< Fn, variadic >::value

(I'm assuming that is_callable_builtin returns true for
functions, references, pointers and members.)

Finally, there's exactly what sort of function type we're
dealing with -- function, reference, pointer or member.
These are handled by separate traits:

  is_function_reference< Fn >::value
  is_member_function_pointer< Fn >::value

That's three (or four if you include the at_c usage to get
the nth parameter, but let's not go there again) subtly
different interfaces. I'm not concerned about the
difference between ::type and ::value -- as I can put ::type
in both cases and get a true_type or false_type.

But that still leaves two different interfaces, which IMO is
one too many. My traits suggestion removed one interface by
ditching the tags, but it wasn't the tag interface that I
disliked /per se/ -- it was the inconsistency.

What if you went the other way and used an exclusively
tag-based interface:

  namespace bft = boost::function_types;

  bft::get< int (), result_type >::type
    // int

  bft::get< int (), parameter_types >::type
    // an empty MPL sequence

  bft::get< void (int*, float), parameter_types >::type
    // an MPL sequence containing (int*, float)

  bft::get< void (int*, float), parameter_type<0> >::type
    // int* -- optional syntactic sugar

  bft::get< void (...), is_variadic >::type
    // true_type

  bft::get< void (...), is_variadic >::value
    // true

  bft::get< void (), is_default_cc >::type
    // true_type

  bft::get< void (*)(), is_pointer >::type
    // true_type

etc... This is not very dissimilar to the existing
is_callable_scalar metafunction, but with addition
is_pointer, is_reference, etc... tags folded in.

> A "reject" vote for a matter of personal taste is pretty
> tough, IMO. But sadly it wouldn't surprise me much after
> reading some of the material from the GIL review...

Hey! I've never said I'm voting to reject ;-)

I said in my original review

| Although most of my comments are negative, I like this
| library, and would like to see it in Boost. I would
| prefer to see some modifications made first, but even in
| the absense of these, I'd still like to see it added.

... and I still feel this way. Just to avoid any doubt, my
vote is to ACCEPT.

--
Richard Smith

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk