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