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









Daniel <yebbliesnospam gmail.com> 