Thanks, yes I have that as an alternate example in my longer notes.  My understanding is that it still suffers from the type-matching problem as traditional for loops.  Your example of:

for (const auto i : std::views::iota(0, count))

only works when count is an int.  Otherwise, if for example count is uint32_t, it would need to be:

for (const auto i : std::views::iota(uint32_t{0}, count)
or:
for (const auto i : std::views::iota(0u, count))
or:
for (const auto i : std::views::iota<uint32_t>(0, count))
or:
for (const auto i : std::views::iota<decltype(count)>(0, count))

or something along those lines, or you will get template instantiation failure compiler error.  I think that if std::views::iota had a constructor overload that was simply the second argument (count) with implicit zero start, then it would be a good option.  However I believe there is interest to reserve such an overload perhaps for infinite ranges?

thanks,
Sophia


On Aug 27, 2019, at 9:41 AM, Justin Bassett <jbassett271@gmail.com> wrote:

When C++20's ranges comes, I'm planning on just:

for (const auto i : std::views::iota(0, count)) {
    ...
}

Which is remarkably similar to Python's for i in range(count). The naming is a bit unfortunate, though.

Does this satisfy the need?

On Tue, Aug 27, 2019, 9:27 AM Sophia Poirier via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
WHAT

A count-based for loop provides a simple declarative means to declare within the loop's scope a zero-based counter variable of the same decayed type as an integral count value (satisfying the Integral concept) and will loop count number of times incrementing the counter variable by one after each iteration.

for (const auto i : count)
{
    std::cout << i << '\n';
}


WHY

As with range-based for loops, it reduces the typical boilerplate of a count-centered for loop and eliminates the the need to correctly declare and match types to the count value, leveraging auto deduction instead.  It provides a declarative means to iterate over a count rather than the imperative original for loop's three-piece construction.  It supports the C++ Core Guidelines P.3: Express intent.

While some might balk at a third for() overload, I believe this addition will actually relegate for(;;) to the esoteric/expert level, the same way that no-one really expects to see:
for (std::container::iterator it = container.begin(); it != container.end(); ++it)
in new code anymore.

Though it has been a couple of decades, I can still remember as a novice C++ programmer frequently slowing down on for loops, pausing to remember which operations exactly happen in each of the three expressions when and for which control flow purpose.  Are function calls in the middle expression executed for each iteration, or only the logical operation?  Will pre-increment vs post-increment cause a logical difference in the third expression? Will it make a performance difference?  Why am I seeing sign mismatch comparison warnings or implicit integer widening conversion warnings?  (Then noisy warnings usually just get disabled.)  Why did the counter overflow or underflow?  If I am decrementing the counter, will I want to test on ==0 or <=0 or <0?  These are uninteresting and burdensome mechanics for the typical idiomatic usage of simply counting up to N.


RELATIONSHIP TO OTHER PROPOSALS

std::ssize() http://wg21.link/P1227 attempts to solve this type of problem, but unfortunately in a rather incomplete fashion.  This problem exists far beyond STL containers and the size() function.  This proposal offers a more complete solution.

Additionally, if [P1110] A placeholder with no name http://wg21.link/P1110 is accepted, then there would be a simple way to create a loop to execute N times without a counter variable if it is unneeded, e.g.:

for (__ : count)
{
    do_something();
}


thanks for your thoughts,
Sophia
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals