Problem with closures

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Fri Jan 12 07:54:32 PST 2007


[edited quotes to fix top-posting]

Bradley Smith wrote:
> Bradley Smith wrote:
>> Chris Nicholson-Sauls wrote:
>>> 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);
>>> }
 >>
 >> 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
 >
 > 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);
 > }

This also works:
-----
// Delegates replaced by functions and TAddN changed to template
// template function instead of template function pointer variable
// (so no delegate or function literals are needed)

import std.stdio;

alias int function(int n) AddFunc;

int TAddN (int N) (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);
}
-----

But I agree that the fact the below doesn't work seems to be a bug:

-----
// Delegates replaced by functions

import std.stdio;

alias int function(int n) AddFunc;

template TAddN (int N) {
   const TAddN = function (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);
}
-----
test.d(6): Error: non-constant expression __funcliteral2

I can understand why the delegate version wouldn't work though. I mean, 
what would the context pointer be?
But the function version should compile IMHO.


More information about the Digitalmars-d-learn mailing list