2

OK, it seems my prior problem is now resolved (I've left it below for reference). However, yet another one crops up - again, seemingly something I'm missing. Further up in this code, I declared the following:

private:

T _data;
BinaryTree!(T) _left; 
BinaryTree!(T) _right;

Then after this, I declared these:

public:
@property T data() {return _data;}
@property BinaryTree!(T) left() {return _left;}
@property BinaryTree!(T) right() {return _right;}

Then, I implemented the following function:

void add (T data) {
    BinaryTree!(T) nearest = findNearest(this, data);
    if (nearest.data > data) {
        nearest.left = new BinaryTree!(T) (data);
    }
    else {
        nearest.right = new BinaryTree!(T) (data);
    }
}

The compiler is protesting that nearest.left and nearest.right aren't properties, although as nearest is a BinaryTree!(T), this seems rather odd. What am I missing?


OLD PROBLEM:

I've recently gotten into D, and was trying to build a binary tree implementation as a way of testing what I've learned by reading about it. Now, I started by declaring it as follows:

class BinaryTree(T)

I figured this would allow me to parametrize some of the stuff the class holds. More specifically:

T _data;
BinaryTree!(T) _left;
BinaryTree!(T) _right;

Now, I then tried writing this:

BinaryTree!(T) findNearest (BinaryTree(T) x, T key) {
    if (x.hasNoChildren || x.data == key) {
        return x; //found it
    }
    else {
        auto compare = x.data;
        if (compare > key) {
            return find (x.left, key);
        }
        else {
            return find (x.right, key);
        }
    }
}

After this, the compiler loudly complained about my function not having a return type. What am I doing wrong here? If it helps to explain, I come from a Java background, and I'm using the dmd compiler inside of Xamarin Studio.

Koz Ross
  • 2,714
  • 1
  • 19
  • 40
  • 2
    Write setters and everything will work. For example: `@property void left(BinaryTree!(T) left) { _left = left; }` – sigod Aug 07 '13 at 09:56
  • Thanks for that. Why is this so, out of interest? The understanding I had of `@property` is that we can have calls like `tree.left` as opposed to `tree.getLeft()`, which is why I'm not sure why you'd use `@property` with _setters_. – Koz Ross Aug 09 '13 at 02:36
  • And `tree.left = new_left;` as `tree.setLeft(new_left);`. http://dlang.org/property.html scroll to bottom. – sigod Aug 12 '13 at 16:52

1 Answers1

4

The only error I can see is a missing ! in the function parameter:

BinaryTree!(T) findNearest (BinaryTree(T) x, T key) {

should be

BinaryTree!(T) findNearest (BinaryTree!(T) x, T key) {

The rest looks fine to me.

Peter Alexander
  • 50,304
  • 10
  • 114
  • 163
  • Thanks for the quick answer! This seems to have fixed it. However, now I'm getting another error when I try to test it in main! I'll give you the whole thing to make sure I'm not doing something stupid: `module main; import std.stdio; import BinaryTree; void main(string[] args) { auto T = new BinaryTree!int (10); writeln(T.hasNoChildren); writeln(T.find(10)); }` The problem is specifically with the line `auto T = new BinaryTree!int (10);`. The compiler doesn't like it because of BinaryTree not being a 'template declaration'. – Koz Ross Aug 06 '13 at 21:09
  • 3
    I think the issue there is that both the module and the type are named `BinaryTree`, so you'll need to write `auto T = new BinaryTree.BinaryTree!int(10);` – Peter Alexander Aug 06 '13 at 21:25
  • 3
    Note, in D, it is more common to have module names in all lowercase. If the module name was different from the class name then you could just use `BinaryTree` without having to first specify the module. – Peter Alexander Aug 07 '13 at 07:33
  • Thanks, that solves it. I just renamed the module and it worked. – Koz Ross Aug 07 '13 at 07:52