Understanding alias template parameters

Paul Backus snarwin at gmail.com
Thu Apr 21 21:47:29 UTC 2022


On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote:
> Hi,
>
> Could someone possibly help me to understand why the commented 
> line doesn't compile?
>
>
> ```d
> import std;
>
> struct MapResult(R,F)
> {
>     R r;
>     const F f;
>     auto empty() { return r.empty; }
>     auto front() { return f(r.front); }
>     void popFront() { r.popFront; }
>     auto save() { return typeof(this)(r.save,f); }
> }
>
> auto myMap(alias f, R)(R r) {
>     return MapResult!(R,typeof(f))(r,f);
> }
>
>
> void main()
> {
>    int function(int) f = x=>2*x;
>    iota(10).myMap!f.writeln;
>    //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this 
> compile?
>
> }
> ```

When you write a lambda without type annotations, like `x => 
2*x`, the compiler interprets it as a function template. So in 
this case, it's the same as if you'd written

```d
T func(T)(T x) { return 2*x; }
iota(10).myMap!func.writeln;
```

The problem is, you can't store a template in a variable:

```d
auto f = func; // doesn't work - func does not have a value
```

So, when you try to create a `MapResult` with the template `x => 
2*x` as one of its member variables, it doesn't work.

By the way, you may have noticed that the error message you got 
says something about variables of type `void` not being allowed. 
That's because of [a long-standing bug][1] that causes `typeof` 
returns `void` when applied to a template. However, that bug is 
not the cause of the error here--even if it were fixed, your code 
still would not work.

[1]: https://issues.dlang.org/show_bug.cgi?id=7947


More information about the Digitalmars-d-learn mailing list