Есть ли способ передать rvalue по ссылке в C ++? - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь создать функциональность «отката» для небольшого назначения базы данных.У меня есть стек двоичных деревьев поиска, которые я использую для хранения резервных копий базы данных:

GenStack<GenBST<Student>> masterStudentStack;

И стек, и BST являются моими собственными реализациями (согласно инструкциям для моего назначения).

У меня нет проблем с переносом копии BST в стек, однако

masterStudentStack.push(*masterStudent);

, когда я пытаюсь получить этот BST и вернуть его к первичному указателю BST, используя:

void rollBack() {
    masterStudent = new GenBST<Student>(masterStudentStack.pop());
}

Я получаю сообщение об ошибке.

Menu.cpp:419:63: error: invalid initialization of non-const reference of 
type ‘GenBST<Student>&’ from an rvalue of type ‘GenBST<Student>’
 masterStudent = new GenBST<Student>(masterStudentStack.pop());
                                     ~~~~~~~~~~~~~~~~~~~~~~^~
In file included from Menu.h:7:0,
             from Menu.cpp:1:
GenBST.h:49:1: note:   initializing argument 1 of 
‘GenBST<T>::GenBST(GenBST<T>&) [with T = Student]’
 GenBST<T>::GenBST(GenBST<T>& other) {
 ^~~~~~~~~

Конструктор копирования для BST работает, когда lvalue передается по ссылке (это объявление для конструктора)

GenBST(GenBST<T>& other);

но я не знаю, как извлечь что-то из стека таким образом, чтобы конструктор копирования это принял.Итак, мой вопрос: могу ли я что-то создать новый BST, используя rvalue "stack.pop ()"?

Спасибо, Мэтью

Редактировать:

После добавления "const "к моему конструктору копирования BST, я получил эту ошибку

In file included from Menu.h:7:0,
             from Menu.cpp:1:
GenBST.h: In instantiation of ‘GenBST<T>::GenBST(const GenBST<T>&) [with T = 
Student]’:
Menu.cpp:419:65:   required from here
GenBST.h:50:22: error: passing ‘const GenBST<Student>’ as ‘this’ argument 
discards qualifiers [-fpermissive]
   if(other.getRoot() == NULL) {

GenBST.h:77:17: note:   in call to ‘GenTreeNode<T>* GenBST<T>::getRoot() 
[with T = Student]’
 GenTreeNode<T>* GenBST<T>::getRoot()
                 ^~~~~~~~~
GenBST.h:54:32: error: binding ‘GenTreeNode<Student>* const’ to reference of 
type ‘GenTreeNode<Student>*&’ discards qualifiers
     copyTree(this->root, other.root);
                          ~~~~~~^~~~
GenBST.h:108:6: note:   initializing argument 2 of ‘void 
GenBST<T>::copyTree(GenTreeNode<T>*&, GenTreeNode<T>*&) [with T = Student]’
 void GenBST<T>::copyTree(GenTreeNode<T> *& thisNode, GenTreeNode<T> *& 
otherNode) {

Вот мой конструктор и метод, который он вызывает:

template <class T>
GenBST<T>::GenBST(const GenBST<T>& other) {
  if(other.getRoot() == NULL) {
    root = NULL;
  }
  else {
    copyTree(this->root, other.root);
  }
}

template <class T>
void GenBST<T>::copyTree(GenTreeNode<T> *& thisNode, GenTreeNode<T> *& 
otherNode) {
  if(otherNode == NULL) {
    thisNode = NULL;
  }
  else {
    thisNode = new GenTreeNode<T>(otherNode->key);
    copyTree(thisNode->left, otherNode->left);
    copyTree(thisNode->right, otherNode->right);
  }
}

Есть идеи?

Редактировать2:

Большое спасибо всем за помощь.Я добавил const в оба метода getRoot () и copyTree (), и теперь у меня одна ошибка.

GenBST.h: In instantiation of ‘GenBST<T>::GenBST(const GenBST<T>&) [with T = 
Student]’:
Menu.cpp:419:65:   required from here
GenBST.h:54:32: error: binding ‘GenTreeNode<Student>* const’ to reference of 
type ‘GenTreeNode<Student>*&’ discards qualifiers
     copyTree(this->root, other.root);
                          ~~~~~~^~~~
GenBST.h:108:6: note:   initializing argument 2 of ‘void 
GenBST<T>::copyTree(GenTreeNode<T>*&, GenTreeNode<T>*&) const [with T = 
Student]’
 void GenBST<T>::copyTree(GenTreeNode<T> *& thisNode, GenTreeNode<T> *& 
otherNode) const {   

1 Ответ

0 голосов
/ 26 ноября 2018

Каноническая форма конструктора копирования принимает ссылку на const-объект для копирования.Концептуально создание копии чего-либо обычно подразумевает, что исходный объект остается неизменным.Вряд ли когда-нибудь возникнет необходимость изменить объект, который вы копируете.Значение может быть связано со ссылкой на const, но не со ссылкой на неконстантный.Если создание копии GenBST на самом деле не влечет за собой изменение объекта, который вы копируете (я предполагаю и искренне надеюсь, что это не так), вы можете просто изменить сигнатуру вашего конструктора копирования на

GenBST(const GenBST& other);
...