How are delegate attributes in fn signature inferred?

wjoe invalid at example.com
Mon May 23 13:44:53 UTC 2022


Hello,

Consider this example:
```d
module foo;

import std.stdio;
import std.algorithm;
import std.traits;
import std.range;

void print(R)(R r) {
   static assert(isIterable!R);
   r.each!writeln;
}

auto construct(R)(R r, ElementType!R delegate(ulong i) fn) {
   static assert(isIterable!R && hasAssignableElements!R);
   ulong i = 1;
   r.each!((ref e) => e = fn(i));
   return r;
}

unittest {
   int[] i; i.length = 4;
   i.construct((ulong i) {return cast(int)(i+i);}).print;
}
```

```shell
> dmd -unittest -main foo.d

Error: template 'foo.construct' cannot deduce function from 
argument types '!()(int[], int function(ulong i) pure nothrow 
@nogc @safe)', candidates are: 'construct(R)(R r, ElementType!R 
delegate(ulong i) fn)'
```

Where's **pure nothrow @nogc @safe** coming from?
Also, why is *(ulong i) {return cast(int)(i+i);}* passed as a 
function?
The error message for passing a delegate is the same except with 
*function* substituted for *delegate*.


More information about the Digitalmars-d-learn mailing list