On Friday, 1 September 2017 at 00:09:16 UTC, H. S. Teoh wrote:
Consider the case where .front returns a subrange. As you state above, copying this subrange does not have defined behaviour. One reason is the difference in semantics between reference types and value types: the assignment operator `=` means different things for each kind of type. `x=y;` for a value type makes a new copy of the value in x, but `x=y;` for a reference type only copies the reference, not the value.
Absolutely, in particular, InputRange shouldn't be assumed copyable. joiner saves whatever was passed to it, in this particular case, result of files.map!(a => a.byLine) which is range itself and is evaluated lazily. This makes every call of .front() to re-evaluate (a => a.byLine) and to call the constructor again, skipping first line every time. The partial solution is simple, force joiner to make immediate evaluation instead of lazy one:
    return joiner(array(files.map!(a => a.byLine)));
here, the array is saved in joiner and no lazy constructor call is performed. However, in general I have a feeling that something is wrong here with design. Copying of InputRanges should be disabled possibly, or lazy range evaluation should be under control. Can't say what is wrong exactly, but something definitely is.


Reply via email to