Unexpected foreach lowering

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 10 13:54:15 PDT 2016


On 8/10/16 2:08 PM, Lodovico Giaretta wrote:
> I'm probably missing something stupid but...
> Why on earth do the two loops in main print a different result?
> It looks like the foreach lowering is ignoring my definition of front...
>
> =====================================================
> import std.stdio, std.container.array;
>
> struct RangeWrapper(Range)
> {
>     Range range;
>     alias range this;
>
>     auto front()
>     {
>         return range.front + 1;
>     }
> }
> auto rangeWrapper(Range)(auto ref Range range)
> {
>     return RangeWrapper!Range(range);
> }
>
> void main()
> {
>     Array!int array;
>     array.insertBack(3);
>
>     foreach (i; rangeWrapper(array[]))
>         writeln(i);           // prints 3, which is wrong
>
>         // isn't the above foreach equivalent to the following loop ?
>
>     for (auto r = rangeWrapper(array[]); !r.empty; r.popFront())
>         writeln(r.front);     // correctly prints 4
> }
> =====================================================
>
> Thank you for your help.

The issue is that it tries using [] on the item to see if it defines a 
range-like thing. Since you don't define opSlice(), it automatically 
goes to the subrange.

This breaks for int[] as well as Array.

If I add opSlice to your code (and return this) it works.

This is definitely a bug, it should try range functions before opSlice. 
Please file.

-Steve


More information about the Digitalmars-d-learn mailing list