Understanding alias template parameters

JG someone at somewhere.com
Fri Apr 22 08:04:16 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?
>
> }
> ```
>
> (I do know that Phobos's map works differently with better 
> performance).


Thank you to all for the great replies. To fix it one could do:

```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) {
         static if(__traits(compiles,f!(typeof(R.init.front)))) {
             auto fun = f!(typeof(R.init.front));
             return MapResult!(R,typeof(fun))(r,fun);
         } else {
         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;

     }
     ```

In response to the change to "alias", which has several upsides
including faster code. I would note it also has some downsides 
including
every lambda produces a new type so that (at the moment) the 
following assert
holds:
```d
auto r = iota(10).map!(x=>x+1);
auto s = iota(10).map!(x=>x+1);
assert(!is(typeof(r)==typeof(s)));
```


More information about the Digitalmars-d-learn mailing list