有没有办法在 C++ 中通过引用传递右值?
Is there a way to pass an rvalue by reference in C++?
我正在尝试为小型数据库分配创建 "rollback" 功能。
我有一堆二叉搜索树,用于存储名为:
的数据库的备份
GenStack<GenBST<Student>> masterStudentStack;
堆栈和 BST 都是我自己的实现(根据我的作业说明)。
我可以毫无问题地将 BST 的副本压入堆栈,
masterStudentStack.push(*masterStudent);
但是,当我尝试检索此 BST 并将其 return 指向我的主要 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 的复制构造函数起作用,(这是构造函数的声明)
GenBST(GenBST<T>& other);
但我不知道如何以复制构造函数接受的方式从堆栈中弹出一些东西。所以,我的问题是:我可以使用右值 "stack.pop()" 创建一个新的 BST 吗?
谢谢,
马修
编辑:
将 "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 {
复制构造函数的规范形式采用对要复制的 const 对象的引用。从概念上讲,复制某物通常意味着原始对象保持不变。几乎不需要修改您正在复制的对象。右值可以绑定到对 const 的引用,但不能绑定到对非常量的引用。除非制作 GenBST
的副本确实需要修改您正在复制的对象(我假设并真诚地希望它不会),您可以简单地将复制构造函数的签名更改为
GenBST(const GenBST& other);
我正在尝试为小型数据库分配创建 "rollback" 功能。 我有一堆二叉搜索树,用于存储名为:
的数据库的备份GenStack<GenBST<Student>> masterStudentStack;
堆栈和 BST 都是我自己的实现(根据我的作业说明)。
我可以毫无问题地将 BST 的副本压入堆栈,
masterStudentStack.push(*masterStudent);
但是,当我尝试检索此 BST 并将其 return 指向我的主要 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 的复制构造函数起作用,(这是构造函数的声明)
GenBST(GenBST<T>& other);
但我不知道如何以复制构造函数接受的方式从堆栈中弹出一些东西。所以,我的问题是:我可以使用右值 "stack.pop()" 创建一个新的 BST 吗?
谢谢, 马修
编辑:
将 "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 {
复制构造函数的规范形式采用对要复制的 const 对象的引用。从概念上讲,复制某物通常意味着原始对象保持不变。几乎不需要修改您正在复制的对象。右值可以绑定到对 const 的引用,但不能绑定到对非常量的引用。除非制作 GenBST
的副本确实需要修改您正在复制的对象(我假设并真诚地希望它不会),您可以简单地将复制构造函数的签名更改为
GenBST(const GenBST& other);