User defined type and foreach
Jim Balter
Jim at Balter.name
Fri Jan 19 10:49:29 UTC 2024
On Friday, 17 November 2017 at 17:55:30 UTC, Jonathan M Davis
wrote:
> When you have
>
> foreach(e; range)
>
> it gets lowered to something like
>
> for(auto r = range; !r.empty; r.popFront())
> {
> auto e = r.front;
> }
>
> So, the range is copied when you use it in a foreach.
Indeed, and the language spec says so, but this is quite wrong as
it violates the specification and design of ranges ... only
forward ranges are copyable and only via their `save` function. I
have an input range that can only be iterated once; if you try to
do so again it's empty ... but the foreach implementation breaks
that. You should be able to break out of the foreach statement,
then run it again (or another foreach) and it should continue
from where it left off, but copying breaks that. I need to know
how many elements of my range were consumed; copying breaks that.
I got around this by having a pointer to my state so only the
pointer gets copied. I would also note that tutorials such as Ali
Çehreli's "Programming in D – Tutorial and Reference" are unaware
of this breakage:
"
Those three member functions must be named as empty, popFront,
and front, respectively. The code that is generated by the
compiler calls those functions:
for ( ; !myObject.empty(); myObject.popFront()) {
auto element = myObject.front();
// ... expressions ...
}
"
More information about the Digitalmars-d-learn
mailing list