May 28, 2015
https://issues.dlang.org/show_bug.cgi?id=14625

          Issue ID: 14625
           Summary: opIndex() doesn't work on foreach container iteration
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P1
         Component: DMD
          Assignee: nobody@puremagic.com
          Reporter: k.hara.pg@gmail.com

A non-range container object iteration `foreach (e; c)` is
implicitly converted to a range iteration, by application of
implicit slicing like as `foreach (e; c[])`.

(Maybe the feature is not well documented in website?
http://dlang.org/statement#foreach-with-ranges
)

struct Range
{
    @property bool empty() { return true; }
    @property int front() { return 0; }
    void popFront() {}
}
struct Container
{
    Range opSlice() { return Range(); }
}
void main()
{
    Container c;
    foreach (e; c) {}
}

On the other hand, new integrated array operator overloading says as follows: http://dlang.org/operatoroverloading#Slice
> To overload a[], simply define opIndex with no parameters:

But, it does not work on the container iteration. Test case is:

// Range struct is same as above
struct Container
{
    Range opIndex() { return Range(); }
    Range opSlice() { assert(0); }
}
void main()
{
    Container c;
    //foreach (e; c) {}   // asserts in opSlice(), NG
    foreach (e; c[]) {}   // calls c.opIndex(), OK
}

The orignal post in d.learn forum: http://forum.dlang.org/thread/vhsyxrroterdmqpgcesc@forum.dlang.org

--