a lambda with arguments has type void?

Artur Skawina via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jun 9 07:37:05 PDT 2016


On 06/09/16 07:20, cy via Digitalmars-d-learn wrote:
> Like this is why it doesn't really make sense:
> 
> import std.stdio;
> 
> auto foo(Callable)(Callable c) {
>   return c(42);
> }
> 
> auto foo2(alias c)() {
>   return c(42);
> }
> 
> void main() {
>   // this works, when you know it's an int delegate(int) beforehand...
>   writeln(foo!(int delegate(int))((arg) => arg + 1));
>   // and this can infer that your argument is an int delegate(int)
>   writeln(foo2!((arg) => arg + 1));

No. `a=>a+1` is a /template/ and is passed as-is to `foo2`. Hence
`c` is a template and it's only instantiated inside that function.
This would compile too:

   auto foo2(alias c)() {
      return c(3.14);
   }


>   // so why doesn't this work, if the compiler can infer that the
>   // argument is an int delegate(int)?
>   static assert(!__traits(compiles,
>      writeln(foo((arg) => arg + 1))));
> }

It can't. It's a template. Templates are not values and can not be
used as runtime function arguments.

The only magic that the compiler does is that it lets you call
callable templates directly - it automatically instantiates them
(using the types of the arguments used for that call). 

artur


More information about the Digitalmars-d-learn mailing list