简体   繁体   中英

how to write a default iterator to a generic list?

i am writing this code a generic list , now in this generic list i did a class for iterator that helds two parameters : one is a pointer to the list he points to . and the other one points to the element in the list he points to ..

now i need to write an insert function that inserts a new element to a given list , with the following rules :: where i insert a new node to the list, and in this function if the iterator poiints to the end of the list the we add the new node to the end of the list else we insert the node one place before the node that the iterator currently points to , and if the iteratot points to a different node then thats an error .

now i want the iterator to be defoult so in case in the tests someone called the function with one parameter i want the iterator to be equal to the end element of the list. the function end i wrote it inside of the list. now in the insert function i did that but i get this error :

cannot call member function "List::iterator List::end()"without object .

#include <iostream>
#include <assert.h>
#include "Exceptions.h"

template <class T>
class List {

public:
    List();
    List(const List&);
    ~List();
    List<T>& operator=(const List& list);
    template <class E>
    class ListNode {
        private:
             ListNode(const E& t, ListNode<E> *next): data(new E(t)), next(next){}
             ~ListNode(){delete data;}
             E* data;
             ListNode<E> *next;
        public:
            friend class List<E>;
            friend class Iterator;
            E getData() const{
               return *(this->data);
            }
            ListNode<E>* getNext() const{
               return this->next;
            }
            };
    class Iterator {
        const List<T>* list;
        int index;
        ListNode<T>* current;
        Iterator(const List<T>* list, int index): list(list),
                index(index),current(NULL){
            int cnt=index;
            while (cnt > 0) {
                current = current->next;
                cnt--;
                    }
        }
        friend class List<T>;
        friend class ListNode<T>;
    public:
       // more functions for iterator
    };
    Iterator begin() const ;
    Iterator end() const;
    void insert(const T& data, Iterator iterator=end());//here i get the error
    void remove(Iterator iterator);
    class Predicate{
    private:
      T target;
    public:
      Predicate(T i) : target(i) {}
      bool operator()(const T& i) const {
        return i == target;
      }
    };
    Iterator find(const Predicate& predicate);
    class Compare{
    private:
      T target;
    public:
      Compare(T i) : target(i) {}
      bool operator()(const T& i) const {
        return i < target;
      }
    };
    bool empty() const;
    int compareLinkedList(ListNode<T> *node1,  ListNode<T> *node2);

private:
   ListNode<T> *head;
   ListNode<T> *tail;
int size;
};

any help would be amazing ! cause i don't know why such a mistake apears .

//insert function just in case : 


template <typename T>
void List<T>::insert(const T& data, Iterator iterator=end()){
    if(iterator.list!=this){
        throw mtm::ListExceptions::ElementNotFound();
        return;
    }
    ListNode<T> *newNode = new ListNode<T>(data, iterator.current);
    if(iterator.index==size){
        if (head == NULL) {
            head = newNode;
            tail=newNode;
            }else{
        Iterator temp(this,size-1);
        temp.current->next=newNode;
            }
        //newNode->next=this->end().current;
           }
    else {
    if (head == NULL) {
    head = newNode;
    tail=newNode;
    }
   else {
       Iterator temp1(this,iterator.index-1);
        temp1.current->next=newNode;
        newNode->next=iterator.current->next;
   }

   }
    size++;
}
void insert(const T& data, Iterator iterator=end());

This is the offending line. A default argument cannot be the result of a member function call. The right tool to achieve what you want is overloading.

void insert(const T& data, Iterator iterator);
void insert(const T& data) { insert(data, end()); }

Here we still defer to the insert function you implemented, but we call end from within the overloads body, where it's allowed.

Don't worry about the indirect call. This is a very small function that's defined inside the class declaration itself. Any decent compiler will inline it completely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM