TDPL: Overloading template functions
Andrej Mitrovic
andrej.mitrovich at gmail.com
Thu Jul 29 08:08:20 PDT 2010
Page 160, code:
import std.algorithm, std.range;
void main() {}
double average() { return 1.0; }
double average(double) { return 2.0; }
// computes average of a set of numbers, passable directly or via an array
double average(double[] values...) {
if (values.empty) {
throw new Exception("Average of zero elements in undefined");
}
return reduce!((a, b) { return a + b; })(0.0, values) / values.length;
}
unittest {
average();
average(2.5);
}
The book states this is an ambiguous call, but I can succesfully compile.
On Thu, Jul 29, 2010 at 4:16 AM, Andrej Mitrovic <andrej.mitrovich at gmail.com
> wrote:
> 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/4f25f510/attachment.html>
More information about the Digitalmars-d
mailing list