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