1

I initialized a test case as a global variable, here:

void InsertNode(BSTNode* &t, const int &key) {
    if (t == NULL) {
        t = new BSTNode;
        t->key = key;
        t->left = t->right = NULL;
    } else {
        if (key != t->key) {
        if (key < t->key)
                InsertNode(t->left, key);
            else
                InsertNode(t->right, key);
        }
    }
}

BSTNode t1[] = {
 {4, &t1[1], &t1[2]},
 {2, &t1[3], &t1[4]},
 {6, &t1[5], &t1[6]},
 {1, NULL, NULL},
 {3, NULL, NULL},
 {5, NULL, NULL},
 {7, NULL, NULL}
};

int main() {
    InsertNode(t1, 0);
    return 0;
}

However, when I try to modify t1, it gives me an error:

invalid initialization of non-const reference of type 'BSTNode*&' from a temporary of type 'BSTNode*'

Could someone explain this for me? Thank you!!

JASON
  • 7,371
  • 9
  • 27
  • 40
  • 3
    Post a compilable minimalistic code sample to demonstrate your problem. – Alok Save Feb 04 '13 at 04:14
  • 1
    @AlanShore that doesn't compile without a `BSTNode` definition. – WhozCraig Feb 04 '13 at 04:19
  • Wait, why is it taking the address of `t1[2]` in the initialization of `t1[0]`? I wouldn't think that's legal. – chris Feb 04 '13 at 04:20
  • @chris Can the compiler not implicitly convert `&t1[2]` into `t1+2`, thereby neglecting the fact that `t1[2]` may not be initialized yet? – us2012 Feb 04 '13 at 04:23
  • @us2012 even if it could (and I don't think it can), an `operator &()` override would really hose up the works. I could see `t1+1` and `t1+2` being almost doable (but I don't think it is either). – WhozCraig Feb 04 '13 at 04:25
  • `t1` is an array, not a pointer. See also http://stackoverflow.com/questions/7454990/why-cant-we-pass-arrays-to-function-by-value – johnsyweb Feb 04 '13 at 04:28
  • @chris [Apparently it is](http://ideone.com/PbwifI), without so much as even a warning. Not that I'd likely ever *use* such a feature, but I was somewhat surprised. – WhozCraig Feb 04 '13 at 04:40

1 Answers1

1

The problem is that your function is stating that it may change the pointer:

void InsertNode(BSTNode* &t, const int &key) {

it is taking a reference to a non-const pointer as a parameter, so it has the potential of modifying that pointer. However when you do this call:

InsertNode(t1, 0);

you are passing in a non-modifiable pointer, since t1 is an array. An array can be used like a pointer, but you can't make that pointer point somewhere else.

One way to deal with this would be to have two different functions:

void InsertNode(BSTNode* &t, const int &key);

void AddNode(BSTNode* t, const int &key) {
    assert(t!=NULL);
    if (key != t->key) {
    if (key < t->key)
            InsertNode(t->left, key);
        else
            InsertNode(t->right, key);
    }
}

void InsertNode(BSTNode* &t, const int &key) {
    if (t == NULL) {
        t = new BSTNode;
        t->key = key;
        t->left = t->right = NULL;
    } else {
        AddNode(t,key);
    }
}

And then call

AddNode(t1, 0);
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • @AlokSave: I added some explanation. See if that makes it clearer. – Vaughn Cato Feb 04 '13 at 04:29
  • 1
    Yes it does now. When I commented on your answer it merely reiterated what the compiler reported with no explanation of why the error and it would not help anybody. The reason makes it clear for people who refer it in future. Also, You don't really need two versions of the function. You simply create a pointer to the global array and pass that to the function. – Alok Save Feb 04 '13 at 04:32