On Wednesday, 28 May 2014 at 07:13:37 UTC, BlackEdder wrote:
I'm trying to write a thin wrapper around redblacktree, but it
seems every object of the class shares the same copy of
redblacktree. Am I doing something wrong or is this a bug.
Minimal code example:
import std.array;
import std.container;
import std.stdio;
class A {
auto tree = new RedBlackTree!string();
}
unittest {
auto a = new A();
a.tree.insert( "a" );
auto b = new A();
writeln( "Should be empty, but is: ", b.tree.array );
writeln( "Should be empty, but has length: ", b.tree.length
);
}
Which results in the following output:
$ rdmd -unittest rbt.d
Should be empty, but is: ["a"]
Should be empty, but has length: 1
I'm using dmd 2.0.65.
The problem is the initialization of A.tree. Short answer, move
it to a constructor and it should work.
Now what I think is going on: default values for member fields
must be known at compile time. This is why structs can do
something like
struct S
{
int i = 5;
}
while they're not allowed to define a default constructor.
So it appears the tree is instantiated at compile time and stored
somewhere, and the reference to that instance is used as the
default value for A.tree. I didn't know this was possible to do
with reference type members, and perhaps it should be disallowed.
This is highly counter intuitive behavior esp. for people coming
from Java.