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.

Reply via email to