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).

Reply via email to