2011-04-14 21 views
1

我正在寫一個二叉樹模板,不明白爲什麼我不能從該模板中的我的一個函數返回節點*。返回參數不能被接受在c + +模板

代碼:

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

我不是100%確定的,但我認爲你不可能真的去像這樣的ACROSS模板。創建一個使用相同模板的類。 – Andrew 2011-04-14 12:07:19

回答

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; 
    } 
} 
+0

我已經在body的公共部分(typedef Node * node;)中定義了typedef,看到您的評論後,但仍然是相同的錯誤:錯誤錯誤C2143:語法錯誤:缺少';'之前'*' – 2011-04-14 12:17:01

+0

我已經編輯了我的答案,爲您提供了一個示例 – Bruce 2011-04-14 13:09:45

+0

我已經拿出來了,但必須在每個節點的末尾添加。它的工作,謝謝你。但是,仍然,爲什麼我不能使用Node *作爲返回參數,即使我完全符合Binary_Tree :: Node *? – 2011-04-14 14:33:24

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語言是不喜歡口齒不清紅寶石,其中一個塊的最後一行是該塊的隱含價值。

事實上,這是一個遞歸調用不會調用以任何方式特殊,它的結束,它只是一個普通的電話,如果你打算回呼的價值,你必須明確地返回它。

+0

我在那裏做遞歸,希望有其他的東西出現,但我同意在最後應該有一個默認返回,爲了安全起見... – 2011-04-14 12:20:12

+0

你有一個非常有效的指向那裏。謝謝你指出我的方式。 – 2011-04-14 14:16:29

5

完全限定的返回類型的查找功能:

Binary_Tree<T>::Node* Binary_Tree<T>::find(T* dat, Node* current){ ... 
+1

爲了能夠使用返回的指針,這加上'struct Node'應該在public部分。 – Mephane 2011-04-14 12:54:57

+0

您可能還需要前面的'typename',表示Node是所有T的類型。 – 2011-04-14 13:34:37

+0

嗯,完全符合條件顯得很有效的,直到我試過,但具有相同的錯誤結束還有這樣一條:警告警告C4346:「Linked_List ::節點」:從屬名稱不是一個類型 錯誤錯誤C2143:語法錯誤:缺少';'之前'Linked_List ::發現' – 2011-04-14 14:28:04

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就是這樣一個常用名字。)
+0

我決定隱藏節點作爲內部結構,供用戶不用擔心。 find()函數僅用於該模板的類內部函數。 – 2011-04-14 14:39:26

+0

這就是我的觀點。如果它是內部的,那麼爲什麼要在公共成員函數中返回一個指向其中的指針呢? – 2011-04-15 01:57:21