$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] disable_if conundrum
From: Marshall Clow (mclow.lists_at_[hidden])
Date: 2011-12-05 15:53:12
On Dec 5, 2011, at 12:20 PM, Jeremiah Willcock wrote:
> 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.
Thanks! 
That compiles - but I don't understand why - or even what the return type ends up being.
I notice that if I change the typedef named in detail:range_pair from 'type' to 'assds' it still compiles.
But if I add the following code:
                bool comp ( int x ) { return x >  10; }
and 	res = Foo ( v, comp );
I get a bunch of compilation errors.
Updated code attached.