Understanding alias template parameters

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Apr 22 00:21:18 UTC 2022


On Thu, Apr 21, 2022 at 09:02:47PM +0000, JG via Digitalmars-d-learn 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?
> 
> }
> ```

Check the compiler's error message carefully:

/tmp/test.d(6): Error: variable `test.MapResult!(Result, void).MapResult.f` variables cannot be of type `void`
           ^^^
The error comes from line 6, which is:

>    const F f;

A lambda literal like `x=>2*x` is a template, so you cannot store it in
a variable. You need to either explicitly wrap it in a delegate, or
forward the alias to your struct as a template parameter, e.g.:

	struct MapResult(alias f, R)
	{
		... // remove the line `const F f;`
	}
	auto myMap(alias f, R)(R r) {
	    return MapResult!(f, R)(r);
	}


T

-- 
Truth, Sir, is a cow which will give [skeptics] no more milk, and so they are gone to milk the bull. -- Sam. Johnson


More information about the Digitalmars-d-learn mailing list