Unexpected foreach lowering

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 10 11:38:00 PDT 2016


On 08/10/2016 11:08 AM, 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.

RangeWrapper does not provide the InputRange interface, so the compiler 
uses 'alias this' and iterates directly on the member range.

I tried making RangeWrapper an InputRange but failed. It still uses 'range'.

// Still fails with these:
     @property bool empty() {
         return range.empty;
     }

     void popFront() {
         range.popFront();
     }

I don't know how the decision process works there.

Ali



More information about the Digitalmars-d-learn mailing list