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