Alias this with array can only be used once

Ali Çehreli acehreli at yahoo.com
Wed Feb 22 16:25:09 PST 2012


On 02/22/2012 03:59 PM, Jonathan M Davis wrote:
 > On Wednesday, February 22, 2012 15:40:41 Ali Çehreli wrote:
 >> On 02/22/2012 03:16 PM, Blake Anderton wrote:
 >>> With an array the above tests work (I assume because each
 >>> operation is implicitly a new slice?).
 >>
 >> It works because the slice itself is copied to count() and count()
 >> consumes that copy internally.
 >>
 >> Now I see the issue here: Why does 'alias this' disable the parameter
 >> copying behavior? Why is the member slice not being copied?
 >>
 >> This must be clarified. Is this a bug? A hole in the spec?
 >
 > I believe that it's quite clear. Think about it. How is the template
 > instantiated? With the type that you give it. And as long as the type 
passes
 > the template constraint, the function will be instantiated with the exact
 > type that you gave it.

This proves that 'alias this' is something to watch out for. It makes 
our type to pass certain constraints but at the end it is still our 
object that gets passed, not the 'alias this'ed member.

The problem here has been that the original type was a class (i.e. a 
reference type). The class variable gets copied to count() and count() 
consumes the one instance of the class.

If the original code used 'struct' instead, this issue would not have 
come up, because then the member of the copy would be consumed. Sneaky! :)

This code passes the asserts:

import std.algorithm;

struct ArrayContainer
{
     int[] values;
     this(int[] v) { values = v; }
     alias values this;
}

void main(string[] args)
{
     auto c = ArrayContainer([1, 2, 3]);
     assert(count(c) == 3); //succeeds
     assert(c.length == 3); //succeeds too
                            //(would fail if ArrayContainer were a class)
}

Ali



More information about the Digitalmars-d-learn mailing list