我正在为二叉树编写一个模板,并且不明白为什么我不能从该模板中的一个函数返回Node *。
代码:
template<class T>
class Binary_Tree{
private:
struct Node{
T* data;
Node *left,*right;
Node(T* dat, Node* l, Node* r) : data(dat),left(l=0),right(r=0) {}
}*root;
public:
Binary_Tree() : root(0) {}
Node* find(T* dat);
....
};
template<class T>
Node* Binary_Tree<T>::find(T* dat, Node* current){
if (*current->data == *dat){
return current;
}else if(*current->data < *dat && current->left == 0){
return current;
}else if(*current->data > *dat && current->right == 0){
return current;
}else if (*current->data < *dat){
find(dat,current->left);
}else if(*current->data > *dat){
find(dat,current->right);
}else{
return 0;
}
}
有什么想法吗?
感谢。
答案 0 :(得分:5)
将返回类型完全限定为查找功能:
Binary_Tree<T>::Node* Binary_Tree<T>::find(T* dat, Node* current){ ...
答案 1 :(得分:1)
根据定义,您的节点是私有的,那么为什么要在公共方法中返回私有类型? 此外,有时,编译器很难使用模板,有时,如果特定标签是变量或类型,则需要让他们知道。您可以使用 typename 关键字。
此外,您可以将节点类放在Binary_Tree之外(选中,它会编译):
template<class T>
class Node {
T* data;
Node<T> *left,*right;
Node<T> (T* dat, Node<T> * l, Node<T> * r) : data(dat),left(l=0),right(r=0) {}
};
template<class T>
class Binary_Tree{
private:
Node<T> *root;
public:
Binary_Tree() : root(0) {}
Node<T>* find(T* dat,Node<T> *); // changed prototype
};
template<class T>
Node<T>* Binary_Tree<T>::find(T* dat, Node<T>* current){
if (*current->data == *dat){
return current;
}else if(*current->data < *dat && current->left == 0){
return current;
}else if(*current->data > *dat && current->right == 0){
return current;
}else if (*current->data < *dat){
return find(dat,current->left); // add missing return
}else if(*current->data > *dat){
return find(dat,current->right); // add missing return
}else{
return 0;
}
}
答案 2 :(得分:1)
您似乎错过了return
中if .. else if ..
块中的两个find
:.
修改强>
以下代码的代码是问题:
template<class T>
Node* Binary_Tree<T>::find(T* dat, Node* current){
if (...) {
..
} else if (*current->data < *dat){
find(dat,current->left);
}else if(*current->data > *dat){
find(dat,current->right);
在这里,您只需调用find
即可结束此功能。您要包含return
语句,如:
template<class T>
Node* Binary_Tree<T>::find(T* dat, Node* current){
if (...) {
..
} else if (*current->data < *dat){
return find(dat,current->left);
}else if(*current->data > *dat){
return find(dat,current->right);
C语言与 lisp 和 ruby 不同,其中块的最后一行是该块的隐含值。
这是一个递归调用的事实并不会使调用以任何方式处于特殊状态,最后它只是一个普通的调用,并且如果您打算返回调用的值,那么明确地返回它。
答案 3 :(得分:0)
基本上,当你这样写:
template<class T> Node* Binary_Tree<T>::find(T* dat, Node* current){
...
怎么知道你在谈论哪个Node*
?你必须明确告诉它。
但还有另一个更深层次的问题。也就是说,你有一个公共函数返回一个指向一个只在内部(私下)知道类的类型的指针。 find()
与来自Node
的调用者有什么关系?根据您的设计,他们唯一可以做到的就是将其传递给公共成员之一。更具体地说,如果您期望调用find()
函数执行类似
p = tree.Find( /* some arguments */);
然后用p->left
做点什么。那不应该编译。
可能的解决方案:
Node
的结构的定义移出类并进入全局范围。 (实际上,更好的是,将它放在命名空间中,因为Node
是一个通用名称。)