Page 160, code:<br><br>import std.algorithm, std.range;<br><br>void main() {}<br><br>double average() { return 1.0; }<br>double average(double) { return 2.0; }<br><br>// computes average of a set of numbers, passable directly or via an array<br>
double average(double[] values...) {<br> if (values.empty) {<br> throw new Exception("Average of zero elements in undefined");<br> }<br> return reduce!((a, b) { return a + b; })(0.0, values) / values.length;<br>
}<br><br>unittest {<br> average();<br> average(2.5);<br>}<br><br><br>The book states this is an ambiguous call, but I can succesfully compile.<br><br><div class="gmail_quote">On Thu, Jul 29, 2010 at 4:16 AM, Andrej Mitrovic <span dir="ltr"><<a href="mailto:andrej.mitrovich@gmail.com">andrej.mitrovich@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">I can't get the example on page 158 to compile, I've tried both versions of reduce:<br>
<br>import std.stdio, std.range;<br><br>@property bool empty(T)(T[] a) { return a.length == 0; }<br>@property ref T front(T)(T[] a) { return a[0]; }<br>
void popFront(T)(ref T[] a) { a = a[1 .. $]; }<br><br>V reduce(alias fun, V, R)(V x, R range)<br> if (isInputRange!R && is(typeof(x = fun(x, range.front))))<br>{<br> for (; !range.empty; range.popFront()) {<br>
x = fun(x, range.front);<br> }<br> return x;<br>}<br><br>unittest {<br> int[] r = [10, 14, 3, 5, 23];<br> <br> // compute the sum of all elements<br> int sum = reduce!((a, b) { return a + b; })(0, r);<br>
assert(sum == 55);<br> <br> // compute minimum<br> int min = reduce!((a, b) { return a < b ? a : b; })(r[0], r);<br> assert(min == 3);<br>}<br><br>void main() { }<br><br>Errors:<br>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<br>
<br>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[])<br><br>reduce.d(31): Error: template instance errors instantiating template<br>
<br>If I comment out the template constraints (the if statements for either version of reduce), the example will compile and the unittests will pass.<div><div></div><div class="h5"><br><br><div class="gmail_quote">On Wed, Jul 28, 2010 at 11:15 PM, Andrej Mitrovic <span dir="ltr"><<a href="mailto:andrej.mitrovich@gmail.com" target="_blank">andrej.mitrovich@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">Should I just keep posting my findings in this thread? I hate to make a new thread for every problem I find.. <br>
<br>Anyway, on Page 150, this code fails:<br><br>auto f = (int i) {};<br>assert(is(f == function));<br><br>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.<div>
<div></div><div><br>
<br><div class="gmail_quote">On Wed, Jul 28, 2010 at 10:56 PM, Rainer Schuetze <span dir="ltr"><<a href="mailto:r.sagitario@gmx.de" target="_blank">r.sagitario@gmx.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
Andrej Mitrovic wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Woops, I got confused. I was thinking about structs, not arrays.<div><br>
<br>
But yeah, in this case a float gets compared to a double and it seems to evaluate to false.<br>
</div></blockquote>
<br>
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<br>
<br>
float f = 2.4; // approximately 2.4000001<br>
double d = 2.4; // approximately 2.3999999999999999<br>
assert(f == d);<br>
<br>
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).<br>
<br>
In contrast, this<br>
<br>
assert(2.4 == 2.4f);<br>
<br>
passes, as the compiler keeps real precision until writing the value to memory and evaluates the expression at compile time.<br>
</blockquote></div><br>
</div></div></blockquote></div><br>
</div></div></blockquote></div><br>