question about foreach, opApply, and delegates

grauzone none at example.net
Mon Jun 8 06:25:43 PDT 2009


Jerry Quinn 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?

The foreach body is like a nested function. Your example is (probably, 
maybe this is wrong/oversimplified) compiled to something like this:

void foo() {
   C c = new C;
   int bla;
   void something(uint v) {
	bla = 123;
	writefln(v);
   }
   c.opApply(&something);
}

Note that &something is a delegate. A delegate is a pair of a context 
pointer and a function pointer. As you said, the context pointer can be 
an object reference. But in this case, it's a raw pointer into the 
stack. That's why you can use variables declared in the containing 
function (foo). I added a variable 'bla' to demonstrate this. When the 
nested function accesses bla, it reads the delegate's context pointer to 
access the stack frame of the containing function.

You could say the foreach statement is a giant pile of syntactic sugar. 
No magic involved. When the break or continue statements are used, 
things get more trickier. That's why the delegate passed to opApply 
returns an int. I think.

Also, this should go into the d.D.learn newsgroup. (Although I think 
it's perfectly fine to post this here, because the "gurus" don't post 
and probably don't even read d.D.learn.)



More information about the Digitalmars-d mailing list