digitalmars.D - Local variable inside delegate literal
- Daniel (20/20) Dec 22 2009 I'm writing some gui code, and am currently trying to make something equ...
- bearophile (41/55) Dec 23 2009 This is D2 code that actually compiles:
- Daniel (23/100) Dec 23 2009 I actually needed it to be a delegate to interact with the rest of my co...
- downs (14/40) Dec 23 2009 This is how you do it in 1.0:
- Sergey Gromov (27/39) Dec 23 2009 First, there are syntax errors in your example. It should be
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 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()); }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
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