question about foreach, opApply, and delegates

Jarrett Billingsley jarrett.billingsley at gmail.com
Mon Jun 8 06:25:41 PDT 2009


On Mon, Jun 8, 2009 at 8:55 AM, Jerry Quinn<jlquinn at optonline.net> wrote:
> Hi, all.  I find myself a little confused about how foreach, opApply, and delegates interact according to the docs.
>
> Foreach on an aggregate will use the opApply call (assuming ranges aren't being used).  So if we use a simple example below, what exactly is the delegate that is passed to opApply?  The docs say a delegate is a pairing of an object reference and a function, where the object is passed as the 'this' parameter to the function.  But that doesn't seem to be the case here.
>
> Is a virtual object with a function encompassing the body of the foreach being silently created and passed in?

Sort of.  The delegate passed into the opApply in this case is
actually the body of the loop.  The compiler transforms the foreach
loop body into a nested function.  Nested functions are delegates, but
their context pointer is a pointer to their enclosing function's stack
frame rather than to an object.  So no object is created, but it still
transparently works like a delegate.  This is also why in D1 returning
nested functions results in undefined behavior: the pointer to the
enclosing function's stack frame is no longer valid.

> Thanks,
> Jerry
>
>
> class C {
>  uint[] a;
>  int opApply(int delegate(ref uint) dg) {
>    int result = 0;
>    for (size_t i=0; i < a.length; i++) {
>      result = dg(a[i]);
>      if (result) break;
>    }
>    return result;
>  }
> }
> void foo() {
>  C c = new C;
>  foreach (uint v; c) { writefln(v); }
> }
>
>



More information about the Digitalmars-d mailing list