On 2/7/20 3:13 PM, Dennis wrote:
If I have an input range with element type `int[3]`, how do I easily turn it into a range of `int` so I can map it? If it were an int[3][] I could simply cast it to an int[] before mapping, but I don't want to eagerly turn it into an array.
I thought of doing this:
```
range.map!(x => x[]).joiner.map!(x => x*2);
```

But it gives:
Error: returning x[] escapes a reference to parameter x, perhaps annotate with return

This is correct. Consider that you did not mark x as ref. So what x actually is is a function local. If you returned x[], you just returned a reference to a local, which is about to go out of scope.

I tried doing:
```
map!((return x) => x[]) // same error
map!((return ref x) => x[]) // does not match, map.front is not an lvalue
```

I can easily work around it with some more code, but I wonder if someone knows an easy solution.

This means your actual input range is not an array (map should forward the lvalueness of it). This means you can't just slice, as you will again return references to the local stack frame.

The only solution I can provide is to wrap the static array into a range (maybe something like this exists in Phobos?):

struct SARange(T, size_t N)
{
   T[N] storage;
   size_t elem;
   auto front() { return storage[elem]; }
   void popFront() { ++elem; }
   bool empty() { return elem >= N; }
}

auto asRange(T : E[N], E, size_t N)(T val) {
   return SARange!(E, N)(val);
}

range.map!(x => x.asRange).joiner.map!(x => x*2);

-Steve

Reply via email to