Reputation: 385
I have a problem with this recursive void function:
void ReadBinaryTree(NODE &p)
{
char ch;
File.get(ch);
if (ch != '#')
{
NODE p = new Node;
p->SetFreq(ch);
ReadBinaryTree(p->Left());
ReadBinaryTree(p->Right());
}
else return;
}
NODE
is a pointer to the class Node and File is an ifstream object.
Left()
and Right()
return NODE
.
The compiler does not accept the p->Left()
and p->Right()
arguments, the error is:
no know conversion for argument 1 from 'NODE {aka Node*} to 'Node *&
Could you help me? How can I save the pointers to Node during the recursion?
Upvotes: 0
Views: 537
Reputation: 3716
The issue is that p->Left()
and p->Right()
are r-values and this means you cannot make references of them. The problem arises because p->Left()
is returning some value (Of type Node *
), which is being copied into the parameter of ReadBinaryTree
.
To fix this, your p->Left()
and p->Right()
functions should return NODE &
values (So that your recursion has access to the exact same pointer as is in the parent node, and not just some copy of it).
Also, NODE p = new Node;
should just be p = new Node;
.
However, can I suggest that you convert this function into one that returns a value? i.e.
NODE ReadBinaryTree(ifstream &File)
{
char ch; File.get(ch);
if(ch != '#')
{
NODE p = new Node;
p->setFreq(ch);
p->Left() = ReadBinaryTree(File);
p->Right() = ReadBinaryTree(File);
return p;
} else return null;
}
This code still needs the left and right accessors to return references.
EDIT: Explanation of why references can't take r-values
p->Left()
(the accessor function) is returning a copy of the left pointer. So while the value is the same as p->left
(the attribute), the location in memory is different, and importantly, p->Left()
has been assigned a temporary memory location, because it is an expression, and it was expecting a variable to be 'put into'. Normally, when you pass the expression into a function, it is 'put into' the parameter it is passed in as, but if that parameter is a reference, it expects there to already be a non-temporary memory location, which it adopts as its own. So, when you pass an expression (which has a temporary memory location) to something expecting a reference, it complains because it was expecting something with an already fixed memory location, for it to adopt.
Upvotes: 0
Reputation: 672
ReadBinaryTree
needs a reference to a pointer, so that it can update the pointer to point to the newly created object. The problem is that Left()
and Right()
only returns the address to the child nodes, but not a reference to the pointer where the address is stored.
So you could change the signature of Left()
and Right()
from:
NODE Left()
to:
NODE & Left()
As a alternative, you could directly pass the pointers where the child nodes are stored, to ReadBinaryTree
:
ReadBinaryTree (p->left)
(This naturally assumes there is a member in Node
called left
)
Upvotes: 0
Reputation: 385274
Make it so that Left
and Right
return references. You are trying to pass temporary values into ReadBinaryTree
, which don't bind to the non-const
reference in the argument list.
Your recursion is broken anyway, since inside the function you're operating on a local NODE p
, not the argument. Maybe you meant p = new Node;
, though it's hard to tell from this.
Upvotes: 2