On Tuesday, June 18, 2019 9:45:33 AM MDT lili via Digitalmars-d-learn wrote:
> Hi Guys:
>     see this code
> ~~~
>      int[] ar = [1,2,3,4,52,34,22];
>      auto h = heapify(ar);
>      assert(h.length() == ar.length);
>      writeln("h:",h);
>      assert(h.empty());
> ~~~
> dmd v2.086.0  run all assert passed. Why?

Looking at std/container/binaryheap.d, heapify returns the type BinaryHeap
which provides the API for an input range but no toString. As such, writeln
likely uses the range API to read the elements and print them. And that's
going to pop all of the elements off in the process. In general, if you pass
a range to something and you don't want it to be consumed, then you need to
call save on it so that you pass a copy (for many ranges, copying them is
equivalent to calling save on them, but that's not part of the range API,
and it's not true for all ranges). However, from the looks of it, the
BinaryHeap is a just a basic input range, not a forward range, so it doesn't
have save. That means that reading it will always consume it. Looking over
BinaryHeap, I don't think that it's actually possible to iterate through its
elements without removing them from the BinaryHeap. As such, you can't print
them without removing them from the BinaryHeap.

- Jonathan M Davis

Reply via email to