Insert array into an AA

Steven Schveighoffer schveiguy at yahoo.com
Fri Aug 19 05:31:23 PDT 2011


On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer <nrgyzer at gmail.com> wrote:

> == Auszug aus Robert Clipsham (robert at octarineparrot.com)'s Artikel
>> On 16/08/2011 20:17, nrgyzer wrote:
>> > Hi everyone,
>> >
>> > I've the following:
>> >
>> > private static ubyte[][2][hash_t] classInstances;
>> >
>> > this() {
>> >
>> >     classInstances[toHash()] = new ubyte[2]; // does not work
>> >
>> > }
>> >
>> > I want insert every class instance into the hashmap. Every class
>> > instance should be contained in the map after the constructor was
>> > called. When I compile my code, I get "Error: cannot implicitly
>> > convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]"
>> > which is logical. But is there any way to insert every instance into
>> > the array and define the array/map for this entry?
>> >
>> > Thanks in advance!
>> Is there any particular reason you're using ubyte[][2][hash_t] there? To
>> keep a reference to each instance simply use:
>> ----
>> class MyClass {
>>      static MyClass[] classInstances;
>>      this() {
>>          classInstances ~= this;
>>      }
>> }
>> ----
>> If you in fact want to have a hashmap indexed by the instances with
>> values of type ubyte[][2], you can do this:
>> ----
>> class MyClass {
>>      static ubyte[][2][MyClass] classInstances;
>>      this() {
>>          classInstances[this] = new ubyte[][2];
>>      }
>> }
>> ----
>> The problem in your original code is that you were using = new ubyte[2]
>> rather than = new ubyte[][2]. Hope this helps.
>
> Ok, that works - thx.
>
> @Steve: I'll delete the entries from the map, but what's about  
> overriding the toHash()-function and return a simply int value?

If two instances return the same hash value (as is easily possible, but  
maybe not for your context), then a collision occurs.  Then opCmp is used  
to determine if they are actually identical.

If you use hash_t as your key, then only one object is stored in the map,  
the other is simply overwritten.

> I also need this map-structure for further steps in my application. I's  
> possible to change it to
>
> ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass]
> ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass]
>
> but I thought one map for the same sense is better.

ubyte[][Object] should work for all class types.

> Btw: I've two classes where one inherits:
>
> class MyClassOne {
>
>    protected {
>       static __gshared {
>          uint counter;
>          uint[MyClassOne] fixedData;
>       }
>       uint otherData;
>
>       this(uint d) {
>          otherData = d;
>       }
>    }
>
>    this() {
>       fixedData[this] = ++counter;
>    }
>
>    @property ref {
>       uint myPropOne() { return fixedData[this]; }
>       uint myPropTwo() { return otherData; }
>    }
>
> }
>
> class MyClassTwo : MyClassOne {
>
>    shared(MyClassOne) supInstance;
>
>    this(uint d, MyClassOne mco) {
>       super(d);
>       supInstance = mco;
>    }
>
>    override ref alias supInstance.myPropOne myPropOne;
>
> }
>
> When I create an instance of MyClassOne and call myPropOne on it, I get  
> "1". When I'm using this instance to create an instance of
> MyClassTwo and call myPropOne, I get "0". Is there anything I'm doing  
> wrong?

That crazy override ref alias line, I have no idea what you're doing  
there.  For sure, override ref is not needed.

I'm surprised all of this compiles.

> What I'm trying to do is: One super-class which contains some fixed data  
> (not inheritable) and some data which are different for each
> class.

Note that protected does not prevent MyClassTwo from changing it.

Also note that even though you've only created one instance of MyClassOne,  
every MyClassTwo instance is a MyClassOne (and calls MyClassOne's  
constructor).  I think you have applied the wrong techniques to solving  
your design.  Without knowing further your design/context, I can't really  
help.

-Steve


More information about the Digitalmars-d-learn mailing list