Boost logo

Boost Users :

Subject: Re: [Boost-users] challange to MPL gurus
From: Robert Ramey (ramey_at_[hidden])
Date: 2011-12-12 23:49:37


Jeremiah Willcock wrote:
> On Mon, 12 Dec 2011, Larry Evans wrote:
>
>> On 12/12/11 17:04, Larry Evans wrote:
>>> On 12/12/11 16:39, Jeremiah Willcock wrote:
>> [snip]
>>> Looking at your code, it seems you solved the problem by removing
>>> the nested specialization of is_end, with a specialization in file
>>> scope of check_unless_end. I've a vague memory of hearing some
>>> similar solution elsewhere. Is there some reason why
>>> specializations cannot occur within the class?
>>>
>>> -regards,
>>> Larry
>>
>> The reason is explained in this thread:
>>
>> http://groups.google.com/group/comp.lang.c++.moderated/browse_frm/thread/c040d6d750bf5c08/26bc1ce0b89b5979?#26bc1ce0b89b5979
>
> I don't see anything in that thread that talks about why member
> templates can't be specialized in-class. I don't see a good reason
> for that limitation; how is a class member specialization different
> from one in a namespace other than that there can be template
> parameters on the class itself?
>
> -- Jeremiah Willcock

First of all I want to thank everyone who contributed to this thread. I
carefully read
every single message and the links. I was really lost.

I was really bothered with the idea that the template specialization would
work
outside the class but not in it - as you were. The links didn't seem on
point on
this subject. I took my original solution and moved the specializations
outside
the class. This failed because the I wasn't defined so I added it do the
template
arguments. Then a few syntax corrections and it started to work - OK,
problem solved - but now I was left with this really annoying feature whose
behavior changed when the specialization was moved out side the class. So
I moved it back in - and voila - worked as expected. Here is my solution:

template<typename I>
struct ForwardIterator {
    template<typename I, typename B>
    struct is_end {};

    template<typename I2>
    struct is_end<I2, false_> {
        typedef typename deref<I2>::type t1;
        typedef typename next<I2>::type t2;
        BOOST_CONCEPT_ASSERT(( ForwardIterator<t2> ));
    };

    typedef typename is_end<
        I,
        typename boost::is_same<
            boost::mpl::l_iter<boost::mpl::l_end>,
            I
>
> type;
    typedef typename boost::mpl::print<
        I
>::type t1;

    BOOST_MPL_ASSERT((
        is_convertible<
            typename I::category,
            forward_iterator_tag
>
    ));
};

Basically, I just had to avoid depending on the "outter" template parameter.
This had bothered
me before but I wasn't aware of the right syntax to avoid it. I had to use
the specialization syntax above rather than the template<> syntax I was
familiar with. So
I guess that resolves the problem.

Again, thanks for everyone who contributed - really would never have found
it by myself.

Robert Ramey


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net