Silver Flash
Silver Flash

Reputation: 1071

C++ is it possible to use a class variable as a default argument

I have a class for a tree as shown below:

class avl
{
   node *root;
public:
    avl(int data){
      root->data = data;
    }

    int get_height(node *head = root){  //error here

        if (head->right == head->left) return 0;
        int l = get_height(head->left);
        int r = get_height(head->right);

        if (l > r) return l+1;
        return r+1;
     }
}

Unsurprisingly this generates an error at the get_height definition. g++ complains it as an "invalid use of non-static data member". Can I amend this issue or should I resort to an inelegant use of a wrapper here. I'd appreciate if you can add some details to what the standard says about the cause of this error.

Upvotes: 2

Views: 73

Answers (1)

songyuanyao
songyuanyao

Reputation: 172924

Unfortunately this is impossible. Non-static class members can't be used as default arguments.

Non-static class members are not allowed in default arguments (even if they are not evaluated), except when used to form a pointer-to-member or in a member access expression.

int b;
class X {
  int a;
  int mem1(int i = a); // error: non-static member cannot be used
  int mem2(int i = b); // OK: lookup finds X::b, the static member
  static int b;
};

From the standard, [dcl.fct.default]/9

A non-static member shall not appear in a default argument unless it appears as the id-expression of a class member access expression ([expr.ref]) or unless it is used to form a pointer to member ([expr.unary.op]). [ Example: The declaration of X​::​mem1() in the following example is ill-formed because no object is supplied for the non-static member X​::​a used as an initializer.

int b;
class X {
  int a;
  int mem1(int i = a);              // error: non-static member a used as default argument
  int mem2(int i = b);              // OK;  use X​::​b
  static int b;
};

The declaration of X​::​mem2() is meaningful, however, since no object is needed to access the static member X​::​b. Classes, objects, and members are described in [class]. — end example ]

As you said you can add an overloaded wrapper function like

int get_height(node *head) {
    ...
}
int get_height() {
    return get_height(this->root);
}

Upvotes: 4

Related Questions