[C++-sig] Re: Adding __len__ to range objects

Raoul Gough RaoulGough at yahoo.co.uk
Mon Aug 11 13:11:05 CEST 2003


David Abrahams <dave at boost-consulting.com> writes:

> Raoul Gough <RaoulGough at yahoo.co.uk> writes:
[snip]
>> in template <...> struct iterator_range, add
>>
>>   typename std::iterator_traits<Iterator>::difference_type
>>   distance () const {
>>     return std::distance (m_start, m_finish);
>>   }
[snip]
>
> It only works for random-access iterators.  You could fix it so that
> it would only create the __len__ function for random-access
> iterators; that would be better.

Yes, that would be easy enough I guess. BTW, do you mean it wouldn't
work at all for (e.g.) forward_iterators, or just that it isn't as
efficient? I thought std::distance worked for most (or all)
categories, but is only constant time for random_access_iterators.
It's still going to be (a lot) faster than the equivalent code in
Python.

>
> Then, also, range() creates an iterator-returning function, not an
> iteratable-returning function.  There are subtle differences.
>
>     for x in some_list:
>        print x
>
>     for x in some_list:
>        print x  # prints the same elements
>
> but:
>
>     for x in some_iterator:
>        print x
>
>     for x in some_iterator:
>        print x  # prints nothing

Yes, I would actually expect this since I know that it is an iterator
pair :-) On the other hand, the following should work OK, unless I'm
mistaken:

iterator_copy = some_iterator
for x in some_iterator: print x
for x in iterator_copy: print x    # Prints same

>
> None of the Python iterators support __len__ and I wonder if it's a
> good idea to add it to an iterator we create.  Your thoughts?

Yes, maybe it isn't such a great idea after all. One real drawback
that I thought of is that adding this might break existing code. A
(broken) user-defined iterator might not provide enough smarts for
std::distance to work, and yet still be compatible with the existing
range support. Adding len would break this, since the distance
function would get generated even if it is never used or wanted.

I can think of two ways around this: add a new range_with_len type
(seems excessive), or provide some way for the client code to access
the generated class_ object to add their own extensions (probably
difficult?)

-- 
Raoul Gough
"Let there be one measure for wine throughout our kingdom, and one
measure for ale, and one measure for corn" - Magna Carta





More information about the Cplusplus-sig mailing list