called copy constructor in foreach with ref on Range

kinke kinke at gmx.net
Mon Jun 22 16:59:45 UTC 2020


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


More information about the Digitalmars-d-learn mailing list