0

My sort function looks like this:

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

But I received next error:

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

What does it mean?

This is the complete code of the 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_ */    
4
  • 2
    format this better, and add the full failing code. Commented Jun 22, 2011 at 18:52
  • 2
    Why not use std::list, which comes with a sort function. Commented Jun 22, 2011 at 18:54
  • I am trying to build my own list container Commented Jun 22, 2011 at 19:18
  • Is there a particular reason why every d--n line in your code has four pending white spaces? Commented Jun 22, 2011 at 19:28

1 Answer 1

4

Either you declare sort as a template function with one template argument (Compare) inside the class. Then your definition has to look as follows:

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

And you also need to remove the now redundant friend class Compare declaration from your List class.

Or you keep Compare and sort as-is. In this case, simply don’t have sort as a template, and omit the Compare template argument:

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

Of course this only works if you have defined (not just declared!) the class Compare before this function.

But this second solution would be highly unorthodox and pretty useless since the compare argument doesn’t make much sense: there is only one Compare class and the user cannot change it. Normally, this should be a template argument (first solution).

Sign up to request clarification or add additional context in comments.

9 Comments

Why did you gave the template parameters T and Compare into separate lines of code (with separate angle brackets)?
@ChristianAmmer Separate angle brackets: because that’s required – these are two separate templates, after all: one concerning the class, and one concerning the method. That’s the whole crux of the question. Separate lines: for readability.
@Konrad Rudolph: Ahh I see, thanks for the further explanation.
I recieved: invalid function declaration no member function sort' declared in List<T>' about the line void List<T>::sort(const Compare& comparer) {
@user808176 Well the message really tells you everything that you need to know: you haven’t declared a matching function sort inside your class. In fact, you have forgotten to provide the template argument Compare in the declaration of the function.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.