Адрес возвращаемого значения указателя - PullRequest
0 голосов
/ 04 июня 2019

У меня есть следующий файл .h

class Node
{
private :
    int m_data;
    Node* m_left;
    Node* m_right;
public:
    Node(int data) : m_data(data), m_left(nullptr), m_right(nullptr) {}
    Node* getLeft() { return m_left; }
    Node* getRight() { return m_right;  }
    int getData() { return m_data;  }
};

class Tree
{
private :
    Node * m_root;
    unsigned int m_size;
    void freeNode(Node*);
    bool insert(Node**, int );
public:
    Tree() : m_size(0) {}
    ~Tree();
    int findMaximumVericalSum();
    bool insert(int);
};

Реализация, я получаю ошибку - что не так и как мне это исправить

'&' требует l-значение

Оператор адреса (&) должен иметь значение l в качестве операнда.

bool Tree::insert(Node** root, int data)
{
    Node* newNode = new Node(data);
    if (*root == nullptr) {
        *root = new Node(data);
    }
    else if (data < (*root)->getLeft()->getData())
    {
        // error '&' requires l-value
        insert(&((*root)->getLeft()), data);
    }
    else if (data > (*root)->getLeft()->getData())
    {

    }
}

Ответы [ 2 ]

7 голосов
/ 04 июня 2019

К моему удивлению, я не смог найти хороший дубликат для заданного вопроса (несмотря на другие проблемы).

Ошибка, которую вы видите, происходит из следующего фрагмента кода:

&((*root)->getLeft())

И может быть значительно упрощен до следующего очень маленького кусочка:

int bar();
void foo(int*);

void baz() {
    foo(&bar());
}

(также можно увидеть на https://gcc.godbolt.org/z/PuwtuT)

Это приводит к точно такой же ошибке компилятора. И причина этого в том, что C ++ запрещает брать адрес prvalue, и хотя обсуждение rvalue / lvalue очень сложно, легко вспомнить, что когда функция возвращает значение, это всегда prvalue. (Если функция возвращает ссылку, это другая история). Однако вы можете передать rvalue по константной или rvalue ссылке.

Я не могу сразу предложить решение вашей проблемы, потому что мне не очень понятно, какова ваша конечная цель. Но я надеюсь, что этот ответ, по крайней мере, направит ваши мысли и позволит вам задать другой вопрос.

3 голосов
/ 04 июня 2019
Node* getLeft()

Эта функция возвращает значение.

return m_left;

Значение prvalue инициализируется из этого выражения. Невозможно получить адрес m_left из prvalue. В более общем смысле, невозможно получить адрес какого-либо prvalue. Операнд оператора addressof должен быть lvalue.

&((*root)->getLeft()

что не так

Здесь операнд оператора addressof является prvalue. Программа некорректна.

как мне это исправить

Не пытайтесь применить оператор addressof к выражению prvalue.

Если вы намереваетесь передать указатель на (*root)->m_left в функцию, вам нужен какой-то способ для доступа к этому члену.

  • Решение состоит в том, чтобы предоставить члену доступ к нему публично или через дружбу.
  • Другой способ - предоставить общедоступный метод получения, который возвращает ссылку, а не копию участника.
  • Третье решение - добавить функцию установки. В этом случае вы можете использовать локальную переменную в качестве аргумента для рекурсии, а затем вызывать установщик с переменной после того, как она была изменена функцией.

Кроме того, Tree::insert объявляется как возвращающий bool, но не содержит никаких операторов возврата. Поведение программы не определено (или было бы, если бы оно было правильно сформировано).

P.S. Ваша функция не обрабатывает случай data == (*root)->getLeft()->getData().

...