
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