2011-06-22 31 views
0

我的排序函數的排序函數如下:C++名單

template <typename Compare, typename T>  
void List<T>::sort(const Compare& comparer){ 
... 
}  

但是我收到一個錯誤:

template definition of non-template void List<T>::sort(const Compare&)'
invalid use of undefined type
class List'

是什麼意思?

這是列表的完整代碼:

template <typename T> class Node;  
template <typename T> class Iterator;  
template <typename T>  
class List{  
private:  
    Node<T> * first;  
    Node<T> * last;  
    int size;  
    friend class Predicate ;  
    friend class Compare;  
public:  
    typedef Iterator<T> iterator;  

    List(){  
     first = NULL;  
     last = NULL;  
     size = 0;  
    }  
    List(const List<T> & l);  
    void pushBack(T element);  
    void insert(const T& element, iterator i);  
    iterator remove(iterator i);  
    iterator find(const Predicate& predicate);  
    void sort(const Compare& comparer);  
    int getSize() const;  
    iterator begin();  
    iterator end();  
    ~List();  
};  

template <class T>  
List<T>::List(const List & l) {  
    first = 0;  
    last = 0;  
    size = 0;  
    for (Node<T> * current = l.first; current != 0; current = current -> next){ 
     pushBack(current -> data);  
    }  
}  

template <typename T>  
void List<T>::pushBack(T element){  
    Node<T>* newnode = new Node<T>(element);  
    if (newnode->prev == NULL) {  
     first = newnode;  
     last = newnode;  
    }else{  
     newnode->prev = last;  
     last->next = newnode;  
     last = newnode;  
    }  
}  

template <typename T>  
void List<T>::insert(const T& element, iterator i){  
    if (i.position == NULL){  
     pushBack(element);  
     ++size;  
     return;  
    }  
    Node<T>* after = i.position;  
    Node<T>* before = after->prev;  
    Node<T>* newnode = new Node<T>(element);  
    newnode->prev = before;  
    newnode->next = after;  
    after->prev = newnode;  
    if (before == NULL) {  
     first = newnode;  
    }  
    else{  
     before->next = newnode;  
    }  
    ++size;  
}  

template <typename T>  
typename List<T>::iterator List<T>::remove(iterator iter){  
     if(iter.position != NULL){  
      Node<T>* remove = iter.position;  
      Node<T>* before = remove->prev;  
      Node<T>* after = remove->next;  
      if (remove == first){  
       first = after;  
      } else{  
       before->next = after;  
      }  
      if (remove == last){  
       last = before;  
      }else{  
       after->prev = before;  
      }  
      iter.position = after;  
      --size;  
      delete remove;  
      return iter;  
     }else{  
     throw ElementNotFound();  
    }  
}  

template <typename T>  
typename List<T>::iterator List<T>::begin(){  
    //iterator iter;  
    //iter.position = first;  
    //iter.last = last;  
    return iterator(first);  
}  

template <typename T>  
typename List<T>::iterator List<T>::end(){  
    return iterator (last);  
}  


template <typename Predicate, typename T>  
List<T>::iterator List<T>::find(const Predicate& predicate){  
    iterator iter;  
    for(iter = begin(); iter != end(); iter = next()){  
     if(predicate(iter.getElement())){  
      return iter;  
     }  
    }  
    return end();  
}  

template <typename Compare, typename T>  
void List<T>::sort(const Compare& comparer){  
    Iterator<T> iter;  
    for(iter = begin(); iter != end(); iter = iter.next()){  
     if(comparer(iter.getElement() , (iter+1).getElement()) != true){  

     }  
    }  
}  

template <typename T>  
int List<T>::getSize() const{  
    return size;  
}  

template <class T>  
List <T>::~List() {  
    Node <T> * firstNode = first;  
    while (firstNode != 0)  {  
     Node <T> * nextNode = firstNode->next;  
     delete firstNode;  
     firstNode = nextNode;  
    }  
}  
template <typename T> class Node {  
private:  
    T data;  
    Node* next;  
    Node* prev;  
    friend class List<T>;  
    friend class Iterator<T>;  
public:  
    Node(T element){  
     data = element;  
     prev = NULL;  
     next = NULL;  
    }  
    ~Node(){}  
};  

template <typename T> class Iterator{  
private:  
    Node<T>* position;  
    Node<T>* last;  
    friend class List<T>;  
public:  
    Iterator(){  
     position = NULL;  
     last = NULL;  
    }  
    Iterator(Node<T> * source): position(source) { }  
    T& getElement()const;  
    bool operator==(Iterator b) const;  
    bool operator!=(Iterator b) const;  
    T & operator*();  
    Iterator & operator++();  
    Iterator & operator++(int);  
    ~Iterator(){}  
};  

template <class T>  
T& Iterator<T>::getElement() const{  
    if(position != NULL){  
     return position->data;  
    }  
    else{  
     throw ElementNotFound();  
    }  
}  

template <typename T>  
bool Iterator<T>::operator==(Iterator b) const{  
    return position == b.position;  
}  

template <typename T>  
bool Iterator<T>::operator!=(Iterator b) const{  
    return position != b.position;  
}  

template <typename T>  
T & Iterator<T>::operator*() {  
    return position->data;  
}  

template <class T>  
Iterator<T> & Iterator<T>::operator++() {  
    position = position->next;  
    return *this;  
}  

template <class T>  
Iterator<T> & Iterator<T>::operator++(int){  
    position = position->next;  
    return *this;  
}  


#endif /* LISTGENERIC_H_ */  
+2

格式更好,並添加完整的失敗代碼。 –

+2

爲什麼不使用'std :: list',它帶有一個排序函數。 –

+0

我正在嘗試構建自己的列表容器 – user808176

回答

4

要麼你聲明sort模板函數與類內的一個模板參數(Compare)。然後,你的定義有如下所示:

template <typename T> 
template <typename Compare> 
void List<T>::sort(const Compare& comparer) { 
    … 
} 

而且你還需要從List類中刪除的冗餘現在申報friend class Compare

你保持Comparesort原樣。在這種情況下,根本沒有sort爲模板,並省略Compare模板參數:

template <typename T> 
void List<T>::sort(const Compare& comparer) { 
    … 
} 

當然,如果你有在此之前定義(不只是聲明!)類Compare這僅適用功能。

但是這第二個解決方案將是非常非正統和漂亮沒用,因爲compare說法沒有多大意義:只有一個Compare類和用戶不能更改它。通常,這個應該是是模板參數(第一個解決方案)。

+0

爲什麼你將模板參數'T'和'Compare'分成不同的代碼行(帶有單獨的尖括號)? –

+0

@ChristianAmmer單獨的尖括號:因爲這是必需的 - 畢竟這些是兩個*獨立的*模板:一個涉及類,一個涉及該方法。這是問題的癥結所在。單獨的行:爲了便於閱讀。 –

+0

@Konrad Rudolph:啊,我明白了,謝謝你的進一步解釋。 –