C ++ можно использовать переменную класса в качестве аргумента по умолчанию - PullRequest
2 голосов
/ 15 апреля 2020

У меня есть класс для дерева, как показано ниже:

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;
     }
}

Неудивительно, что это приводит к ошибке при определении get_height. G ++ жалуется на это как «недопустимое использование элемента данных non-stati c». Могу ли я исправить эту проблему или я должен прибегнуть к незаконному использованию обертки здесь. Буду признателен, если вы добавите некоторые детали к тому, что стандарт говорит о причине этой ошибки.

1 Ответ

4 голосов
/ 15 апреля 2020

К сожалению, это невозможно. Non-stati c члены класса не могут использоваться в качестве аргументов по умолчанию.

Non-stati c члены класса не допускаются в аргументах по умолчанию (даже если они не оцениваются), за исключением случаев, когда они используются для формирования указателя на член или в выражении доступа к члену.

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;
};

Из стандарта [dcl.fct.default] / 9

Элемент, не связанный со статусом c, не должен появляться в аргументе по умолчанию, пока он не появится как id-выражение элемента выражение доступа к члену класса ( [expr.ref] ) или если оно не используется для формирования указателя на член ( [expr.unary.op] ). [ Пример: Объявление X​::​mem1() в следующем примере неверно сформировано, поскольку не предоставлен объект для нестатического c члена X​::​a, используемого в качестве инициализатора.

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;
};

Однако, объявление X​::​mem2() имеет смысл, поскольку для доступа к static member X​::​b не требуется никакого объекта. Классы, объекты и члены описаны в [class] . - конец примера ]

Как вы сказали, вы можете добавить перегруженную функцию-оболочку, например

int get_height(node *head) {
    ...
}
int get_height() {
    return get_height(this->root);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...