Template argument deduction from a function call question

John Colvin via Digitalmars-d digitalmars-d at puremagic.com
Wed Apr 1 11:08:53 PDT 2015


On Wednesday, 1 April 2015 at 17:57:12 UTC, Dzugaru wrote:
> Following recent IRC discussion.
>
> I want to write a generic list aggregate function that works 
> with builtin types like int[] as well as custom classes/structs 
> that define front, empty, popFront:
>
> import std.range;
>
> ElementType!S aggregate(alias func, S)(S list, ElementType!S 
> accum = ElementType!S.init)
> if(is(typeof(func(accum, accum)) == typeof(accum))) {	
>     foreach(ref e; list) {
>         accum = func(accum, e);
>     }
>     return accum;	
> }
>
> Now I use it:
>
> auto min1 = aggregate!((a,  b) { return a < b ? a : b; }, 
> int[])([2,4,1,3,5], int.max);
> auto min2 = aggregate!((a,  b) { return a < b ? a : b; }, 
> MyRange)(new MyRange(), int.max);
>
> That works ok.
>
> Now I don't want to specify template argument S, it can be 
> deduced from the function call, right?
>
> auto min1 = aggregate!((a,  b) { return a < b ? a : b; 
> })([2,4,1,3,5], int.max);
>
> Doesn't work! "Error: template math.aggregate cannot deduce 
> function from argument types..."
>
> Now try this:
> //No second parameter - leave it to be default
> auto sum = aggregate!((a,  b) { return a + b; })([2,4,1,3,5]);
>
> And it deduces S just fine.

a)
isn't this almost, if not exactly, the same as 
std.algorithm.reduce?

b)
you can write nice things like this:
auto min = [2,4,1,3,5].aggregate!((a,  b) => a < b ? a : 
b)(int.max);

c)
the deduction failure looks like a bug to me, perhaps there is a 
good reason why it can't work in the general case.


More information about the Digitalmars-d mailing list