On Saturday, 18 April 2015 at 16:26:57 UTC, Max Klyga wrote:
On 2015-04-18 13:46:19 +0000, Chris said:
The following:
import std.stdio : writefln;
import std.range.primitives : isInputRange, hasLength;
void main() {
size_t[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
doSomething(a); // works
doSomething(a[0..5]);
// ---> Error: template slices.doSomething cannot deduce
function from argument types !()(ulong[]), candidates are:
// slices.d(11): slices.doSomething(R)(ref R r) if
(isInputRange!R && hasLength!R)
doSomething!(size_t[])(a[0..5]);
// ---> Error: doSomething (ref ulong[] r) is not callable
using argument types (ulong[])
}
void doSomething(R)(ref R r)
if (isInputRange!R && hasLength!R) // etc..
{
foreach (ref n; r) {
writefln("%d * 2 = %d", n, n * 2);
}
}
//EOF
a[0..5] is not recognized as size_t[]. If I give the compiler
a hint with !(size_t[]), it complains again, i.e. I can not
pass the slice as a reference.
A workaround is
size_t[] b = a[0..5];
doSomething(b);
However, this comes with a serious performance penalty in for
loops (even if I predefine b and reuse it in the loop).
to!(size_t[])(a[0..5]) is even worse.
Any thoughts or tips?
a[0..5] is an R-value, and cannot be passed by reference.
As you noticed, once you use a variable - everything works
because only L-values can be passed by reference.
Also why are you passing slices by reference? Slices do not
copy the memory they point to when passed by value.
Doh! You're right! My bad. However, this makes the function less
generic, but it doesn't matter here.