Subject: Re: [boost] [range] [general] making member functions SFINAE-friendly
From: Jonathan Wakely (jwakely.boost_at_[hidden])
Date: 2013-02-18 13:15:13


On 18 February 2013 18:04, Dave Abrahams wrote:
>
> on Mon Feb 18 2013, Nathan Ridge <zeratul976-AT-hotmail.com> wrote:
>
>>> Could you share a use case that requires to depend on size()
>>> specifically rather than the iterator category?
>>
>> Given an arbitrary range r, determine its size by the fasest
>> means possible.
>>
>> If we use std::distance, we can do it in O(1) for std::vector,
>> O(n) for std::map, and O(n) for std::forward_list.
>>
>> If we can detect whether "r.size()" is a valid expression,
>> and use that if available, and std::distance otherwise, then
>> we have O(1) for std::vector, O(1) for std::map, and O(n) for
>> std::forward_list. Notice how that's an improvement for
>> std::map.
>
> But you can't detect that in general. If you're trying to make this
> work in generic code, simply fixing it for iterator_range doesn't fix
> anything.

It fixes my generic template so it can be used with iterator_range.

What's the general case you're referring to?

Do you mean because there are other cases (apart from iterator_range)
where a size() member function exists, but must not be called?

>> However, if detecting whether "r.size()" is a valid expression
>> cannot be done reliably (for example, if we determine that for
>> iterator_range<I> where I is not random-access it is a valid
>> expression, but then that static-asserts on us), then we
>> can't use this approach.
>
> Then you can't use this approach (in general).

Why? What other range-like types provide an size() member that
appears to be callable but must not be called?