Boost logo

Boost :

From: Joel de Guzman (joel_at_[hidden])
Date: 2003-10-23 09:42:59

David Abrahams <dave_at_[hidden]> wrote:
> "Joel de Guzman" <joel_at_[hidden]> writes:
>> How about:
>> template <class I>
>> inline typename mpl::deref<I>::type
>> operator*(I)
>> {
>> typedef typename mpl::deref<I>::type result;
>> return result();
>> }
>> Then:
>> typedef mpl::list<int, char, std::string> tlist;
>> mpl::begin<tlist>::type i1;
>> int i = *i1;
>> mpl::next<i1>::type i2;
>> char c = *i2;
>> mpl::next<i2>::type i3;
>> std::string s = *i3;
>> This is how it's done in Fusion.
> Aren't you a little worried about introducing such a general overload
> for operator*, even though mpl::deref does tend to limit it through
> SFINAE a bit?

I am worried. This is in fact an issue that I want to address soon.
I'm glad you asked.

Here's the actual deref implemementation:

    template <typename Tag>
    struct deref_traits
        template <typename Iterator>
        struct impl {};

    template <typename Iterator>
    struct result_of_deref
        typedef typename
            deref_traits<typename Iterator::tag)>::
                template impl<Iterator>::type

    template <typename Iterator>
    inline typename result_of_deref<Iterator>::type
    operator*(Iterator const& i)
        return deref_traits<typename Iterator::tag>::
            template impl<Iterator>::apply(i);

Here, MPL style tag-dispatching allows unrelated iterator types
to play along nicely.

There are 2 solutions I can think of:

1) Have all iterators inherit from a base (BAD!)
2) Have an is_tuple_iterator<I> meta-function (better?)

I am of the opinion now that we need the is_tuple_iterator<I> metafunction
to address this issue. If we did, it would solve (through enable_if) all-
encompassing functions such as the operator* above. There are others:
next(i), prior(i) etc.

I'd love to hear your thoughts. Perhaps there's another solution I am
missing? Comments?


Joel de Guzman

Boost list run by bdawes at, gregod at, cpdaniel at, john at