Frequent cannot deduce function from argument types

John Colvin via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Oct 16 09:48:52 PDT 2015


On Friday, 16 October 2015 at 15:48:59 UTC, Edwin van Leeuwen 
wrote:
> Just wondering if anyone has any tips on how to solve/avoid 
> "cannot deduce function from argument types" when relying on 
> template programming.
>
> I run into these problems all the time. Current one was when I 
> tried:
>
> ```
> auto ys = NumericLabel(groupedAes.front.map!((t)=>t.y));
> ```
>
> NumericLabel is a pretty minimal templated InputRange, with as 
> only requirement on the argument that it is also an InputRange. 
> I then get the following compile error:
>
> ```
> source/ggplotd/geom.d(83,35): Error: struct 
> ggplotd.aes.NumericLabel cannot ded
> uce function from argument types !()(MapResult!(__lambda2, 
> FilterResult!(__lamb
> da2, Aes!(double[], "x", double[], "y", string[], "colour")))), 
> candidates are:
> source/ggplotd/aes.d(515,1):        ggplotd.aes.NumericLabel(T) 
> if (isInputRang
> e!T)
> ```
>
> As far as I know MapResult always returns an input range and as 
> you can see there is only one candidate of NumericLabel, so to 
> be honest it looks relatively straightforward to me.

Without seeing more code I can't be 100% sure, but I think it's 
just that you're expecting explicit function template 
instantiation (IFTI) for work for constructors, but it doesn't. 
you have to explicitly provide the template arguments or use a 
free function that forwards to the constructor.

> Now I can define the type specifically (and/or typeof) but it 
> seems like there should be a better way.
>
> In this case typeof isn't even happy:
> ```
> source/ggplotd/geom.d(84,17): Error: constructor 
> ggplotd.aes.NumericLabel!(MapResult!(__lambda2, 
> FilterResult!(__lambda2, Aes!(string[], "x", string[], "y", 
> string[], "colour")))).NumericLabel.this (MapResult!(__lambda2, 
> FilterResult!(__lambda2, Aes!(string[], "x", string[], "y", 
> string[], "colour"))) range) is not callable using argument 
> types (MapResult!(__lambda3, FilterResult!(__lambda2, 
> Aes!(string[], "x", string[], "y", string[], "colour"))))
> ```
>
> If we look closely, it expects a __lambda2 as the MapResult 
> argument, but it gets a __lambda3.
>
>
> I am able to work around it by converting the mapresult to an 
> array, but I'd rather use a lazy solution.

Sadly lambdas aren't currently comparable for equality. Maybe on 
day...

If you use the string lambda "a.y" it will probably work.

The more general workaround is to create a temporary variable and 
then use typeof on that, then use that temporary variable.

The idiomatic solution in this case though is to use a function 
as mentioned above.


More information about the Digitalmars-d-learn mailing list