Boost logo

Boost :

Subject: Re: [boost] disable_if conundrum
From: Jeremiah Willcock (jewillco_at_[hidden])
Date: 2011-12-05 15:20:34


On Mon, 5 Dec 2011, Marshall Clow wrote:

> On Dec 5, 2011, at 11:39 AM, Jeffrey Lee Hellrung, Jr. wrote:
>
>> On Mon, Dec 5, 2011 at 11:30 AM, Jeremiah Willcock <jewillco_at_[hidden]>wrote:
>>
>>> On Mon, 5 Dec 2011, Marshall Clow wrote:
>>>
>>> I have a function that returns a pair of iterators.
>>>> There's also a version that takes a comparison predicate.
>
> [ snip]
>
>>>> I want to provide a range-based version of it.
>
> [ snip ]
>
>>>> Ok. There's a problem.
>>>> If I call:
>>>> foo ( first, last )
>>>> I get an error, because there are two perfectly good two argument
>>>> candidates.
>>>>
>>>> Fine. Been there, seen that. I can use disable_if to make sure that the
>>>> second range based version is only "active" when the arguments are
>>>> different types. It's verbose, but it (usually) works
>
> [ more snippage ]
>
>>>> But this time it does not! I get a compile error telling me that the
>>>> compiler can't deal with boost::range_iterator<XXX>::**type, when XXX =
>>>> some random iterator. It seems that the compiler wants to evaluate all the
>>>> parameters of disable_if_c before deciding whether or not to SFINAE it (I
>>>> guess that's not unreasonable, but it's not what I want)
>>>>
>>>> Apparently, all the other times that I did this, the return type of the
>>>> function was not a dependent type of the template arguments.
>>>>
>>>> Any suggestions for a workaround here?
>>>>
>>>
>>> Look at lazy_disable_if -- it doesn't get the nested "type" member of the
>>> type you give it unless the condition evaluates to false.
>>>
>>
>> Just to supplement: also use an extra level of indirection, a metafunction
>> that maps Range to the return type of foo. So will look like
>> boost::lazy_disable_if_c< condition, foo_result< Range > >::type.
>>
>
> Yeah, that didn't seem to work for me.
> So - here's some code.
> And here's some error messages (from clang 3.0):

Your call to range_pair was not lazy enough -- on line 46, try
"detail::range_pair<Range>" instead of "typename
detail::range_pair<Range>::type". That worked for me at least on GCC 4.4.

-- Jeremiah Willcock


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