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