digitalmars.D - Local variable inside delegate literal
- Daniel <yebbliesnospam gmail.com> Dec 22 2009
- bearophile <bearophileHUGS lycos.com> Dec 23 2009
- Daniel <yebbliesnospam gmail.com> Dec 23 2009
- downs <default_357-line yahoo.de> Dec 23 2009
- Sergey Gromov <snake.scaly gmail.com> Dec 23 2009
I'm writing some gui code, and am currently trying to make something equivalent
to this:
int delegate()[] funcs;
funcs.length = 3;
foreach(i, ref f; funcs)
{
f = int() { return i; }
}
foreach(f; funcs)
{
writeln(f());
}
Prints:
3
3
3
I want it to print
0
1
2
Is there anyway to get this behaviour using delegate literals initialized with
a runtime loop?
Dec 22 2009
Daniel:I'm writing some gui code, and am currently trying to make something equivalent to this: int delegate()[] funcs; funcs.length = 3; foreach(i, ref f; funcs) { f = int() { return i; } } foreach(f; funcs) { writeln(f()); }
This is D2 code that actually compiles: import std.stdio: writeln; void main() { auto funcs = new int delegate()[3]; foreach (i, ref f; funcs) f = { return cast(int)i; }; foreach (f; funcs) writeln(f()); } This is a good version in D2: import std.stdio: writeln; class Foo { int i; this(int i) { this.i = i; } int opCall() { return this.i; } } void main() { auto funcs = new Foo[3]; foreach (i, ref f; funcs) f = new Foo(i); foreach (f; funcs) writeln(f()); } Or even cheaper: import std.stdio: writeln; struct Foo { int i; this(int i) { this.i = i; } int opCall() { return this.i; } } void main() { auto funcs = new Foo[3]; foreach (i, ref f; funcs) f = Foo(i); foreach (f; funcs) writeln(f()); } Often the better code is not the most compact one, but the most explicit one. Bye, bearophile
Dec 23 2009
bearophile Wrote:Daniel:I'm writing some gui code, and am currently trying to make something equivalent to this: int delegate()[] funcs; funcs.length = 3; foreach(i, ref f; funcs) { f = int() { return i; } } foreach(f; funcs) { writeln(f()); }
This is D2 code that actually compiles: import std.stdio: writeln; void main() { auto funcs = new int delegate()[3]; foreach (i, ref f; funcs) f = { return cast(int)i; }; foreach (f; funcs) writeln(f()); } This is a good version in D2: import std.stdio: writeln; class Foo { int i; this(int i) { this.i = i; } int opCall() { return this.i; } } void main() { auto funcs = new Foo[3]; foreach (i, ref f; funcs) f = new Foo(i); foreach (f; funcs) writeln(f()); } Or even cheaper: import std.stdio: writeln; struct Foo { int i; this(int i) { this.i = i; } int opCall() { return this.i; } } void main() { auto funcs = new Foo[3]; foreach (i, ref f; funcs) f = Foo(i); foreach (f; funcs) writeln(f()); } Often the better code is not the most compact one, but the most explicit one. Bye, bearophile
I actually needed it to be a delegate to interact with the rest of my code, but I used the idea of making a copy of the index variable each loop iteration, using a generating function returning a closure. Thanks for your help. import std.stdio: writeln; void main() { auto funcs = new int delegate()[3]; int delegate() makedg(int i) { return { return i; }; } foreach (i, ref f; funcs) f = makedg(i); foreach (f; funcs) writeln(f()); } Or void main() { auto funcs = new int delegate()[3]; foreach (i, ref f; funcs) f = (int i) { return { return i; }; }(i); foreach (f; funcs) writeln(f()); }
Dec 23 2009
Daniel wrote:I'm writing some gui code, and am currently trying to make something equivalent to this: int delegate()[] funcs; funcs.length = 3; foreach(i, ref f; funcs) { f = int() { return i; } } foreach(f; funcs) { writeln(f()); } Prints: 3 3 3 I want it to print 0 1 2 Is there anyway to get this behaviour using delegate literals initialized with a runtime loop?
This is how you do it in 1.0: import std.stdio, std.bind; void main() { auto funcs = new int delegate()[3]; foreach (i, ref f; funcs) f = bind((int i) { return i; }, i).ptr(); foreach (f; funcs) writefln(f()); } --outputs-- 0 1 2
Dec 23 2009
Daniel wrote:int delegate()[] funcs; funcs.length = 3; foreach(i, ref f; funcs) { f = int() { return i; } } foreach(f; funcs) { writeln(f()); }
First, there are syntax errors in your example. It should be f = delegate int() { return i; }; Second, this works in D2: foreach(i, ref f; funcs) { void blah() { auto j = i; f = delegate int() { return j; }; } blah(); } But this doesn't, outputs 2, 2, 2: foreach(i, ref f; funcs) { auto j = i; f = delegate int() { return j; }; } And this crashes: foreach(i, ref f; funcs) { ({ auto j = i; f = delegate int() { return j; }; })(); } I think these 3 variants should be equivalent.
Dec 23 2009









Daniel <yebbliesnospam gmail.com> 