Alias this with array can only be used once

Jonathan M Davis jmdavisProg at gmx.com
Wed Feb 22 14:35:12 PST 2012


On Wednesday, February 22, 2012 23:16:41 Blake Anderton wrote:
> Why doesn't this work? I'm assuming I'm not fully understanding
> how "alias this" interacts with ranges (i.e. the range isn't
> being reset after count is finished with it), but I'm not sure
> how to fix this either:
> 
> import std.algorithm;
> 
> class ArrayContainer
> {
> int[] values;
> this(int[] v) { values = v; }
> alias values this;
> }
> 
> void main(string[] args)
> {
> auto c = new ArrayContainer([1, 2, 3]);
> assert(count(c) == 3); //succeeds
> assert(c.length == 3); //FAILS - is actually zero
> }

I believe that the problem stems from the fact that count is being 
instantiated with ArrayContainer rather than int[]. That means that when it 
gets processed, it ends up operating on the array directly rather than on a 
slice. If ArrayContainer were a struct rather than a class, then this would 
work.

But by doing what you're doing, you've managed to create a type that 
effectively conflates a range and a container. So, when you pass it to range-
based functions, it _will_ be consumed.

You really shouldn't give direct access to the array like that. It's only 
going to cause you trouble. Containers should _not_ be ranges, and using alias 
this makes your ArrayContainer a range.

Instead, you should provide an opSlice to get the array. Then you'd do

assert(count(c[]) == 3);
assert(c[].length == 3);

The explicit [] would be required to call opSlice, since ArrayContainer would 
then not be passable to count (which it really shouldn't be anyway).

However, if you're really married to the idea of using alias this, then the 
above code will work with your current implementation, since it forces the 
array to be sliced, and count therefore gets instantiated with int[] rather 
than ArrayContainer.

But again, I _really_ advise against having a container which is a range. It's 
a _bad_ idea which is only going to cause you trouble.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list