On 2014-02-12 19:36, David Krauss wrote:
> On Feb 13, 2014, at 7:44 AM, Matthew Woehlke wrote:
>> Is there a C++1Y equivalent of this python snippet:
>>
>> for x in range(y):
>>
>> ...? I'm thinking something like:
>>
>> for (auto x : ???(y))
>>
>> What is the expression to use in the above? Is it part of STL,
>> and/or has anyone made such a proposal?
>
> The Python range() constructs a list container without lazy
> semantics. So the C++ equivalent would be to define a function
> returning a std::vector<std::size_t> . Not terribly interesting.
Well, sure, but that wasn't really the point (if it helps, pretend I
wrote 'xrange' instead). I expect a C++ implementation would return
something like a magic iterator, such that the total storage is
~3*sizeof(T) where T is (in the previous example) decltype(y).
> I had thought that Python list comprehensions allowed working with a
> generator to avoid putting the whole range in memory first
(OT: xrange does that.)
> To get a C++ range-for to loop with a generator, just define a class
> whose begin returns an InputIterator interface to the desired
> generator, and end can peek inside the generator to evaluate the
> termination condition.
That's roughly what I ended up doing. The thing is, this:
for (T i = 0, end = func(); i < end; ++i)
...is so insanely common (probably *the* most common for loop), and also
not very easy to write with AAA¹:
auto const end = func();
for (auto i = decltype<end>{0}; i < end; ++i)
...that, even though I can (and did) create my own version easily
enough, it feels like the standard library really ought to offer a way
to write it Python-style using a C++11 range-based for loop:
for (auto const i : index_range(func()))
(See how much prettier and easy to write that is?)
Aside: Apparently template type deduction doesn't allow index_range to
be a class. I had to make it a free function returning an index_range_t.
(Since of course having to specify the type defeats the purpose.)
Note that the reason I got started on this was because I'd seen one too
many places where someone wrote:
for (int i = 0, end = func() /* etc... */)
...where the return type of func() is e.g. size_t / long long /
something else that shouldn't be coerced into 'int'. (Which is also a
great reason to use AAA... except that it's overly awkward in this
instance.)
(¹
http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/)
--
Matthew