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 23:35:45


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

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

> I think you are still missing what MEMBER_TYPE is used for in other
> contexts. This is when you need to supply a type whose type depends on some
> unknown T and is nested to some depth, and the type may or may not exist. In
> this case using complicated logic checking on whether or not HAS_TYPE exists
> becomes difficult. Now I grant you I may be able to build a better
> MEMBER_TYPE based on your idea above, and I will look into it.
>

Hmmm..very true, I guess something like that could and will come in handy.
The use case I'm thinking of is

typedef typename boost::mpl::eval_if<
    has_type_value_type<T>,
    get_type_value_type<T>,
    boost::mpl::identity< some_default_value_type >
>::type value_type;

I think one of the things I don't like about the current setup is that there
are separate HAS_TYPE and MEMBER_TYPE macros, and hence separate
metafunctions, and I'd imagine implementation-wise they largely do the same
thing. Indeed, MEMBER_TYPE is probably implemented in terms of HAS_TYPE,
and likewise for their corresponding metafunctions, right? If I want to do
both "has" queries and "get" queries, then I have to invoke both HAS_TYPE
and MEMBER_TYPE macros. I guess I *could* use valid_member_type< typename
member_type_xxx<T>::type > to implement has_type_xxx<T>, is that correct?

I also don't think the *name* MEMBER_TYPE / member_type_xxx really conveys
well what this macro / metafunction combination does; I don't have any
alternatives at the moment.

This might not be a good idea, but maybe it could lead a better
alternative. What if we added a nested template get to has_type_xxx that
was a unary metafunction? The semantics could be

has_type_xxx<T>::template get<>::type => equivalent to T::xxx (and errors
if a nested type with no such name exists)
has_type_xxx<T>::template get<U>::type => if T has a nested type named
xxx, evaluates to xxx, else evaluates to U

Also despite your feeling that the mullary type metafunctions should go away
> they still, in my mind, are valuable as an alternate syntax to the macro
> metafunctions even with your has_type extension idea.
>
[...]

> I still feel that if I add your idea it will be added as an addition and
> not as a complete replacement of anything else. My reasoning is that not
> everyone is as knoweldgable about MPL and as comfortable with lambda
> expressions as you are.
>

That would make 3 or 4 ways (depending on how you count it) to do the same
thing (deeply nested type introspection):

1) the solution described in "Nested Types" using (only) MEMBER_TYPE /
member_type_xxx;
2) the solution described in "Using Nullary Type Metafunctions" using TTI
metafunctions;
3) the solution described in "Using Nullary Type Metafunctions" using TTI
metafunction classes; and
4) the proposed new solution using Boost.MPL lambda expression predicates
within the has_type_xxx queries.

I think, as a general rule, if you have 3 or 4 ways to do the same thing,
you're asking for confusion. I see potential value in being able to extract
the nested types "softly" *something like* what MEMBER_TYPE does now, but I
do find solutions 1, 2, and 3 at least as complicated as 4 for doing purely
introspection queries on deeply nested types. I'm afraid neither of us,
however, are a good judge of the learning effort any of the above 4
techniques require :/ I wonder if others can share their thoughts on
this...?

Regarding your desire to keep the nullary type metafunctions...shouldn't one
be able to turn *any* metafunction into a "nullary type metafunction" in a
generic fashion, similar to how boost::mpl::quote[n] can turn any
metafunction into a metafunction class? I would think providing such a
generic component would be more useful (and, ultimately, less work, less
documentation, and less maintenance) than providing a specialized TTI
nullary type metafunction for each TTI metafunction category. What do you
think about adding such a component to Boost.MPL?

Regarding others' knowledge of Boost.MPL, I think we should keep in mind
that we're squabbling (well...I'm squabbling) about an advanced (in my
opinion) use of TTI, and the amount of Boost.MPL knowledge one needs to
effectively use TTI in this way is, I think, relatively small (placeholder
expressions + boost::mpl::lambda). I think the learning curve would be
relatively shallow if given a couple of examples. And you typically only
need boost::mpl::lambda if you're introspecting 2 levels deep.

- Jeff


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