Problem with closures
Bradley Smith
digitalmars-com at baysmith.com
Thu Jan 11 22:37:16 PST 2007
Nevermind. I figured it out. The following works.
import std.stdio;
alias int delegate(int n) AddFunc;
template addN(int N) {
AddFunc addN() {
return delegate int (int i) { return i + N; };
}
}
void apply (int[] array, AddFunc func) {
foreach (inout i; array) {
i = func(i);
}
}
void main () {
int[] numbers = [1,2,3] ;
writefln("numbers before = ", numbers);
apply(numbers, addN!(40));
writefln("numbers after = ", numbers);
}
Bradley Smith wrote:
> Using DMD 1.0, I get errors on the template.
>
> closureWithTemplate.d(19): delegate
> closureWithTemplate.TAddN!(40).__dgliteral2 is a nested function and
> cannot be accessed from main
> closureWithTemplate.d(6): Error: non-constant expression __dgliteral2
>
>
> Bradley
>
> Chris Nicholson-Sauls wrote:
>> Lutger wrote:
>>> Alain wrote:
>>>> Frits van Bommel Wrote:
>>>>
>>>>> Alain wrote:
>>>>>> AddFunc addN(int n) {
>>>>>> int add(int i) {
>>>>>> return i + n;
>>>>>> }
>>>>>> return &add; // the add function captured will remember the
>>>>>> value of n
>>>>>> }
>>>>> [snip]
>>>>>> Am i missing something?
>>>>> You shouldn't return delegates to nested functions, just like you
>>>>> shouldn't return pointers to local variables.
>>>>> Delegates to nested functions contain a pointer to the stack frame
>>>>> of the enclosing function. If that function has returned, the stack
>>>>> frame may be corrupted (especially if you have called another
>>>>> function, like apply(), since then).
>>>>
>>>> How come this compiles? Is it a bug ?
>>>>
>>>> Alain
>>>
>>> This is valid code. It is up to the programmer to make sure the
>>> delegate doesn't use vars that are out of scope. There was some talk
>>> about this, to copy the 'evironment' for later use, it might be
>>> solved in the future.
>>>
>>> std.bind might be of use here.
>>
>> As could a template.
>>
>> <code>
>> import std .stdio ;
>>
>> alias int delegate(int n) AddFunc;
>>
>> template TAddN (int N) {
>> const TAddN = (int i) { return i + N; } ;
>> }
>>
>> void apply (int[] array, AddFunc func) {
>> foreach (inout i; array) {
>> i = func(i);
>> }
>> }
>>
>> void main () {
>> int[] numbers = [1,2,3] ;
>>
>> writefln("numbers before = ", numbers);
>> apply(numbers, TAddN!(40));
>> writefln("numbers after = ", numbers);
>> }
>> </code>
>>
>> -- Chris Nicholson-Sauls
More information about the Digitalmars-d-learn
mailing list