2011-06-22 4 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

sort関数に付属する 'std :: list'を使わないのはどうでしょうか? –

+0

私自身のリストコンテナを構築しようとしています – user808176

答えて

4

はどちらかあなたがクラス内の1つのテンプレート引数(Compare)とテンプレート関数としてsortを宣言する。次に、あなたの定義は次のように見ています

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引数はあまり意味がありませんので、この第2の解決策は、非常に異例とかなり役に立たない:そこだけ Compareクラスがあり、ユーザーはそれを変更することはできません。通常、このはテンプレート引数(最初の解決策)であるべきです。

+0

なぜテンプレートパラメータ 'T'と' Compare'をコードの別々の行に書いたのですか? –

+0

@ChristianAmmer別の山括弧:これは必須なので、結局2つの別々の*テンプレートです。つまり、クラスに関するものとメソッドに関するものです。それが問題の全体の要点です。別々の行:読みやすくするため。 –

+0

@ Konrad Rudolph:ああ、私は詳細な説明をいただき、ありがとうございます。私は受け取っていない –