On Thursday, 24 September 2020 at 11:15:11 UTC, ddcovery wrote:
[...]
Example: I tried with a global function

Dot!R dt(alias fun, T, R)(Dot!T t){
 auto f = cast(R function(T)) unaryFun!fun;
 return t.dot!R(f);
}
[...]

the problem is the template can't automatically determine the type "R". All the template parameters need to be resolvable from the arguments you pass into it, R is something magic where it doesn't know where it comes from.

To keep the R like you want to right now you can do the following:

Dot!(typeof(unaryFun!fun(T.init))) dt(alias fun, T)(Dot!T t){
        return t.dot(t => unaryFun!fun(t));
}
or
Dot!R dt(alias fun, T, R = typeof(unaryFun!fun(T.init)))(Dot!T t){
        return t.dot(t => unaryFun!fun(t));
}

Note that this might instantiate unaryFun twice though. The second alternative here allows users to overwrite R and just provides a default (might have useful use cases too)


Alternatively a lot easier would be to just return auto and do:

auto dt(alias fun, T)(Dot!T t){
        return t.dot(t => unaryFun!fun(t));
}

This doesn't allow users to overwrite the return type exactly but it simplifies implementation and doesn't look like it would generate any double instantiation.

Reply via email to