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.

Reply via email to