类型const节点的绑定参考*&到节点*const
我正在尝试实现一个通用树,并且在函数getsizerecursive
行1
为什么不能使用const node*& root
。同样,我在第2行
中遇到了同样的错误。编译器给出了一个我无法理解的错误。
graph.cpp: In function 'int getSizeRecursive(const node*&)':
graph.cpp:56:40: error: binding reference of type 'const node*&' to 'node* const' discards qualifiers
56 | for(const node* &child : root->children) // line 2
| ^~~~~~~~
graph.cpp: In function 'int main()':
graph.cpp:69:36: error: binding reference of type 'const node*&' to 'node*' discards qualifiers
69 | cout << getSizeRecursive(t.root) << endl;
| ~~^~~~
graph.cpp:51:35: note: initializing argument 1 of 'int getSizeRecursive(const node*&)'
51 | int getSizeRecursive(const node* &root){ // line 1
| ~~~~~~~~~~~~~^~~~
[Finished in 2.9s]
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
class node{
public:
int data;
vector<node*> children;
node(int val){
data = val; // this->data = data
}
~node(){
for(int i = 0 ;i<children.size();i++){
if(!children[i])
delete children[i];
}
}
};
class GenericTree{
public:
node* root; // line 3
int size;
GenericTree(vector<int> nums){
stack<node*> st;
size = 0;
for(int i = 0;i<nums.size();i++){
node *n = new node(nums[i]);
if(i == 0){
root = n;
st.push(n);
++size;
}else{
if(n->data == -1){
st.pop();
}else{
// cout << "In me" << endl;
st.top()->children.push_back(n);
st.push(n);
++size;
}
}
}
}
// tells us the number of nodes
int getSize(){
return size;
}
};
int getSizeRecursive(const node* &root){ // line 1
if(root->children.size()==0)
return 1;
int size = 0;
for(const node* &child : root->children) // line 2
size += getSizeRecursive(child);
return size+1;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
freopen("error.txt","w",stderr);
#endif
vector<int> v{10,20,-1,30,50,-1,60,-1,-1,40,-1,-1};
GenericTree t(v); // node that tree has been created
cout << t.size << endl;
cout << getSizeRecursive(t.root) << endl;
return 0;
}
我从中可以理解的是,编译器无法将引用到const Node
const pointer to node
,但我的问题是为什么它会服用<代码> t.root 作为const指向节点
的指针,而实际上只是指针到Node
(请参阅第3行)。
我是C ++的新手。任何帮助将不胜感激。
编辑:我之所以使用const*&amp; root
是因为我不想将root的副本传递给getsizerecursive
,但是在此期间,由于我已通过参考,我已经使用了const
,以便此参考仅读取根指针而不修改它。
I am trying to implement a generic tree and in the function getSizeRecursive
line 1
why cannot i use const node* &root
. Similarly, i am getting the same mistake in line 2
.The compiler is giving an error which i am not able to comprehend.
graph.cpp: In function 'int getSizeRecursive(const node*&)':
graph.cpp:56:40: error: binding reference of type 'const node*&' to 'node* const' discards qualifiers
56 | for(const node* &child : root->children) // line 2
| ^~~~~~~~
graph.cpp: In function 'int main()':
graph.cpp:69:36: error: binding reference of type 'const node*&' to 'node*' discards qualifiers
69 | cout << getSizeRecursive(t.root) << endl;
| ~~^~~~
graph.cpp:51:35: note: initializing argument 1 of 'int getSizeRecursive(const node*&)'
51 | int getSizeRecursive(const node* &root){ // line 1
| ~~~~~~~~~~~~~^~~~
[Finished in 2.9s]
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
class node{
public:
int data;
vector<node*> children;
node(int val){
data = val; // this->data = data
}
~node(){
for(int i = 0 ;i<children.size();i++){
if(!children[i])
delete children[i];
}
}
};
class GenericTree{
public:
node* root; // line 3
int size;
GenericTree(vector<int> nums){
stack<node*> st;
size = 0;
for(int i = 0;i<nums.size();i++){
node *n = new node(nums[i]);
if(i == 0){
root = n;
st.push(n);
++size;
}else{
if(n->data == -1){
st.pop();
}else{
// cout << "In me" << endl;
st.top()->children.push_back(n);
st.push(n);
++size;
}
}
}
}
// tells us the number of nodes
int getSize(){
return size;
}
};
int getSizeRecursive(const node* &root){ // line 1
if(root->children.size()==0)
return 1;
int size = 0;
for(const node* &child : root->children) // line 2
size += getSizeRecursive(child);
return size+1;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
freopen("error.txt","w",stderr);
#endif
vector<int> v{10,20,-1,30,50,-1,60,-1,-1,40,-1,-1};
GenericTree t(v); // node that tree has been created
cout << t.size << endl;
cout << getSizeRecursive(t.root) << endl;
return 0;
}
What i can understand from this is that compiler is not able to bind the reference to pointer to const node
to const pointer to node
but my question is that why it is taking t.root
as const pointer to node
whereas in actual it is just a pointer to node
(see line no 3).
I am novice in c++. Any help would be appreciated.
EDIT: The reason i have used const* & root
is because i did not want to pass a copy of root to getSizeRecursive
but during that since i have passed by reference i have used const
so that this reference just only reads the root pointer and not modify it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我们来看看根据情况下每个错误的原因。此外,我将尝试通过步骤解释事情。
案例1
在这里,我们考虑由于该陈述而引起的第一个错误:
现在要了解为什么由于上述语句而遇到错误,让我们以逐步的方式理解每个术语的含义:
步骤1: <
<代码> root 是A non-const lvalue参考 to
const node
的非const指针。这意味着我们允许我们更改root
ref的指针(因为我们有nonconst lvalue ref),但是我们不允许更改实际的node
。该指针指向的对象。步骤2
root-&gt; roots
isconst vector&lt; node*&gt;
,因为我们不允许更改node
node < /代码>指针指向的对象如上所述。基本上,对象的指向本身就是
const
,这又意味着其数据成员也被视为const
。作为儿童
是数据成员,因此将其视为const
,因此root-&gt; children
isconst vector&lt; node* &gt;
。请注意,此步骤的结论是,我们有一个带有类型
节点*
的元素的const向量。步骤3
现在,
const node*&amp; child
表示child
是 non-const lvalue引用 nonconst指针const Node
。同样,这意味着我们允许我们更改向量内部的指针。但这是一个问题,因为我们从上面的步骤2中学到了const vector&lt; node*&gt;
,这意味着我们不应允许我们更改位于向量内部的指针。因此,您会得到上述错误。解决案例1
至 solve 的解决方案,您需要确保通过添加 低级const来更改位于
const vector
内部的指针如下所示:上面的作品是因为现在
child
是 lvalue引用对非Conconst节点对象的const指针。情况2
在这里,我们考虑由于表达式引起的第二个错误:
此处传递的参数
t.root
是node*
,而参数为const node*&amp ;
。现在,传递的参数被隐式转换为const Node*
,但转换的结果将是一个rvalue。但是,由于参数root
是 nonconst lvalue参考 to const node 的非const指针它不能绑定到rvalue。这基本上是与您将使用的错误相同的错误:
解决情况2的解决方案
基本上,给定类型
t
可以绑定到t&amp;
或t const&amp; < /code>虽然给定类型
const t
可以绑定到t const&amp;
。在您的示例中,传递的参数为node*
这意味着它可以绑定到node*&amp;
以及node*const&amp;
。 。为了解决此问题,您可以将lvalue引用到const lvalue参考文献,如下所示:
在您的示例中,这意味着:
Let's see the reason for getting each of the error on case by case basis. Moreover, i'll try to explain things in steps.
Case 1
Here we consider the 1st error due to the statement:
Now to understand why we get error due to the above statement, let's understand the meaning of each term in step by step manner:
Step 1:
root
is a non-const lvalue reference to a non-const pointer toconst node
. This means that we're allowed to change the pointer to whichroot
refers(since we've a nonconst lvalue ref) but we're not allowed to change the actualnode
object to which that pointer is pointing.Step 2
root->children
isconst vector<node*>
since we're not allowed to change thenode
object to which the pointer is pointing as discussed in step 1 above. Basically, it is as if the pointed to object is itselfconst
which in turn means its data members are treated asconst
as well. And aschildren
is a data member so it is treated asconst
and thusroot->children
isconst vector<node*>
.Note the conclusion of this step is that we have a const vector with elements of type
node*
.Step 3
Now,
const node* &child
means thatchild
is a non-const lvalue reference to a nonconst pointer to aconst node
. Again, this means that we're allowed to change the pointer residing inside the vector. But this is a problem because we learnt from step 2 above that we've aconst vector<node*>
meaning that we should not be allowed to change the pointer residing inside the vector. And hence you get the mentioned error.Solution to case 1
To solve this you need to make sure that there is no way to change the pointer residing inside the
const vector
by adding a low-level const as shown below:The above works because now
child
is a lvalue reference to a const pointer to a nonconst node object.Case 2
Here we consider the 2nd error due to the expression:
Here the passed argument
t.root
is anode*
while the parameter is aconst node* &
. Now, the passed argument is implicitly convertible toconst node*
but result of that conversion will be an rvalue. But since the parameterroot
is an nonconst lvalue reference to a non-const pointer to const node it cannot be bound to an rvalue.This is basically the same error that you will get using:
Solution to Case 2
Basically, a given type
T
can be bound toT&
orT const&
while a given typeconst T
can be bound toT const&
. And in your example, the passed argument isnode*
meaning it can be bound to bothnode*&
as well asnode*const&
.To solve this you can make the lvalue reference to a const lvalue reference as shown below:
In your example, this means:
Working demo