
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@osl.iu.edu>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