On Monday, 22 June 2020 at 16:25:11 UTC, Jonathan M Davis wrote:
The reason that foreach copies the range is simply due to how
the code is lowered. e.g.
foreach(e; range)
{
}
essentially becomes
for(auto r = range; !r.empty; r.popFront())
{
auto e = r.front;
}
And the fact that a copy is made is likely simply a result of
it mimicking what happens with arrays.
I was trying to explain/guess the rationale for that copy (not in
terms of how it's implemented, but why it's implemented that
way). This 'mimicking-an-array' doesn't make any sense to me. If
the original idea wasn't to make sure the range is reusable
afterwards, I guess it's done for implementation simplicity, to
promote an rvalue range to the required lvalue.
If copying a range is considered to be generally unsafe and a
common pitfall (vs. the save() abomination), maybe range-foreach
shouldn't allow any lvalue ranges in the 1st place, thus not
making any copies and forcing the user to specify some rvalue (as
returned by `range.save()`, or `move(range)` if destructive
iteration is indeed intended).