TDPL: Overloading template functions

Andrej Mitrovic andrej.mitrovich at gmail.com
Wed Jul 28 19:16:14 PDT 2010


I can't get the example on page 158 to compile, I've tried both versions of
reduce:

import std.stdio, std.range;

@property bool empty(T)(T[] a) { return a.length == 0; }
@property ref T front(T)(T[] a) { return a[0]; }
void popFront(T)(ref T[] a) { a = a[1 .. $]; }

V reduce(alias fun, V, R)(V x, R range)
    if (isInputRange!R && is(typeof(x = fun(x, range.front))))
{
    for (; !range.empty; range.popFront()) {
        x = fun(x, range.front);
    }
    return x;
}

unittest {
    int[] r = [10, 14, 3, 5, 23];

    // compute the sum of all elements
    int sum = reduce!((a, b) { return a + b; })(0, r);
    assert(sum == 55);

    // compute minimum
    int min = reduce!((a, b) { return a < b ? a : b; })(r[0], r);
    assert(min == 3);
}

void main() { }

Errors:
reduce.d(31): Error: template reduce.reduce(alias fun,V,R) if
(isInputRange!(R) && is(typeof(x = fun(x,range.front)))) does not match any
function template declaration

reduce.d(31): Error: template reduce.reduce(alias fun,V,R) if
(isInputRange!(R) && is(typeof(x = fun(x,range.front)))) cannot deduce
template function from argument types !(__dgliteral1)(int,int[])

reduce.d(31): Error: template instance errors instantiating template

If I comment out the template constraints (the if statements for either
version of reduce), the example will compile and the unittests will pass.

On Wed, Jul 28, 2010 at 11:15 PM, Andrej Mitrovic <
andrej.mitrovich at gmail.com> wrote:

> Should I just keep posting my findings in this thread? I hate to make a new
> thread for every problem I find..
>
> Anyway, on Page 150, this code fails:
>
> auto f = (int i) {};
> assert(is(f == function));
>
> I've checked via typeid(), and f is a delegate by default, not a function.
> I've tested it both in a function's scope and in module scope, with the same
> results.
>
>
> On Wed, Jul 28, 2010 at 10:56 PM, Rainer Schuetze <r.sagitario at gmx.de>wrote:
>
>>
>> Andrej Mitrovic wrote:
>>
>>> Woops, I got confused. I was thinking about structs, not arrays.
>>>
>>>
>>> But yeah, in this case a float gets compared to a double and it seems to
>>> evaluate to false.
>>>
>>
>> 2.4 has no exact representation as a floating point value, as it is
>> 2^^2*0.6, so the mantissa is 3/5. It is rounded after 24 bits for float, but
>> after 53 bits for a double. As a result
>>
>>        float f = 2.4; // approximately 2.4000001
>>        double d = 2.4; // approximately 2.3999999999999999
>>        assert(f == d);
>>
>> fails, because the comparison is done after converting the truncated float
>> to double (as long as the compiler does not issue SSE instructions with
>> single precision).
>>
>> In contrast, this
>>
>>        assert(2.4 == 2.4f);
>>
>> passes, as the compiler keeps real precision until writing the value to
>> memory and evaluates the expression at compile time.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100729/5c14b2f6/attachment-0001.html>


More information about the Digitalmars-d mailing list