Boost logo

Boost :

Subject: Re: [boost] [TTI] Review for The Type Traits Introspection library by Edward Diener **extended**
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-07-17 22:49:43


On Sun, Jul 17, 2011 at 5:06 PM, Edward Diener <eldiener_at_[hidden]>wrote:

> On 7/17/2011 7:02 PM, Jeffrey Lee Hellrung, Jr. wrote:
>
[...]

> To reiterate what I had
>> above, I propose the following to all be equivalent:
>>
>> has_member_function_xxx< Result (T::*)( Arg0, Arg1 )>
>> has_member_function_xxx< T, Result ( Arg0, Arg1 )> // my personal
>> preference, probably
>> has_member_function_xxx< T, Result, boost::mpl::vector2< Arg0, Arg1> >
>>
>
> First and third are fine. It is what now exists for
> BOOST_TTI_HAS_COMP_MEMBER_**FUNCTION and BOOST_TTI_HAS_MEMBER_FUNCTION
> respectively.
>
> The second, even if you like it, is unnecessary, and I also use it for
> BOOST_TTI_HAS_COMP_STATIC_**MEMBER_FUNCTION so I do not want to create
> confusion.
>

No, you're right, it isn't necessary. Let me point out that, strictly
speaking, neither is the third, as if you want to use
has_member_function_xxx in a Boost.MPL placeholder expression, I think
boost::function_types::member_function_pointer [1] gives you what you need.
Regarding the confusion with the syntax for querying static member
functions...can you elaborate on what, exactly, would be confusing?

[Also, let me point out, I *myself* have used the "I think it is
unnecessary" argument to argue for the *removal* of certain constructs in
TTI, so...touche!]

I'm assuming the syntax is still fair game for discussion, so, if not, I
apologize. But if so, please bear with me, and let's actually look at all
of our alternatives. I see 4 potential syntaxes here (let's start with
non-const member functions):

has_member_function< R (T::*)( U0, U1 ) > // A
has_member_function< T, R ( U0, U1 ) > // B
has_member_function< T, R, vector2< U0, U1 >, Tag > // C (Tag optional)
has_member_function< member_function_pointer< vector4< R, T, U0, U1 >, Tag
>::type > // D (Tag optional)

B, to me, would usually be the most convenient, as it has almost no
syntactic baggage. Additionally, it still allows the T parameter to be a
Boost.MPL placeholder expression, which is likely the most common parameter
for a placeholder expression (I'm guessing). So I think B should be
included.

The only advantage A seems to offer over B is it would be necessary to allow
D. Is there some meta-information (e.g., calling conventions) that can be
added to member function pointers but not function types...? If so, I guess
that alone might necessitate the inclusion of A, assuming it's more
convenient to specify that using the Boost.FunctionTypes Tag parameter.

I presume the original motivation for including C was to allow various parts
of the query to be Boost.MPL placeholder expressions. D does allow this and
requires no additional syntax to be directly supported by
has_member_function other than A, but maybe it's too verbose. If you think
D is too verbose, then inclusion of C is justified.

BTW, if you do has_member_function< T, R, Tag >, is it automatically
interpreted as has_member_function< T, R, vector0<>, Tag >, or does it error
because it tries to use Tag as a Boost.MPL sequence? I don't know if you
thought about this, so I thought I should bring it up. FWIW, I would prefer
forcing the user to be more explicit, i.e., force the user to explicitly
including the vector0<> or empty_sequence type to indicate an empty argument
list.

 By the way, how do you check for const member functions? I don't remember
>> seeing anything about this in the documentation. I would assume something
>> like
>>
>> has_member_function_xxx< Result (T::*)( Arg0, Arg1 ) const>
>> has_member_function_xxx< T const, Result ( Arg0, Arg1 )>
>> has_member_function_xxx< T const, Result, boost::mpl::vector2< Arg0,
>> Arg1>
>>
>
> For the first, BOOST_TTI_HAS_COMP_MEMBER_**FUNCTION, you have it correct.
> For the third, BOOST_TTI_HAS_MEMBER_FUNCTION, it would be:
>
> has_member_function_xxx< T, Result, boost::mpl::vector2< Arg0, Arg1>,
> boost::function_types::const_**qualified>
>

Yuck. Would you consider using the cv-qualification of T to determine the
cv-qualification of the member function to query?

> I could also try to combine BOOST_TTI_HAS_COMP_STATIC_**MEMBER_FUNCTION
> and BOOST_TTI_HAS_STATIC_MEMBER_**FUNCTION but that will be a little
> harder because they both begin with the enclosing type while the former
> follows the 'Result, boost::mpl::vector2< Arg0, Arg1>' syntax while the
> latter follows with the 'Result ( Arg0, Arg1 )' syntax.
>

Well, Result can never be a function type, so...I think you're good :)

- Jeff

[1]
http://www.boost.org/doc/libs/1_47_0/libs/function_types/doc/html/boost_functiontypes/reference/synthesis.html#boost_functiontypes.reference.synthesis.member_function_pointer


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