在c ++模板中无法接受返回参数

时间:2011-04-14 12:04:46

标签: c++ templates

我正在为二叉树编写一个模板,并且不明白为什么我不能从该模板中的一个函数返回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;
    }
}

有什么想法吗?

感谢。

4 个答案:

答案 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)

您似乎错过了returnif .. 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是一个通用名称。)