0

I know questions like this have been asked a ton, so I am super sorry if my question is indeed identical to those. I've tried to find the solution to my problem, but none of the given solutions have resolved the error.

I am trying to change a linked list class into a template. I am getting two of the same error ("Expected unqualified-id") when overloading operators.

Below are the code snippets that are getting the error:

template <typename DataType> LinkedList<DataType>& template <typename DataType>LinkedList<DataType>::operator=(const LinkedList &aCopy){ //assignment operator //error seen here
    while(root!=nullptr){
        Node* oneBefore= root;
        root =root->next;
        delete oneBefore;
    }
    Node *newNode= new Node;
    Node *temp=aCopy.root;
    root=newNode;

    while(temp!=nullptr){
        newNode->value=temp->value;
        temp=temp->next;
        if(temp!=nullptr){
            newNode->next=new Node;
            newNode=newNode->next;
        }
        else{newNode->next=nullptr;}
    }
    return *this;
}
template <typename DataType> typename LinkedList<DataType>::Iterator template<typename DataType> LinkedList<DataType>::Iterator::operator++(DataType){//error seen here
    return *this;
}

and here is my full code, in case that is necessary:

  template <typename DataType>
  class LinkedList {
  public:


    struct Node {
      //Node(Node *aNext=nullptr) : next(aNext) {}
        DataType value;   //this is the value you want to save
        Node *next;  //this points to the next node in the list (or nullptr)
    };
    //friend class Iterator; //do Ineed this even though it's a nested class

    Node *root;

    //---------------------------------------------------------------

    //add a NESTED Iterator class...
    class Iterator {
    public:
        Iterator();//default constructor
        //Iterator() : current(nullptr) {}
        Iterator(Node* aNode);
        //Iterator(Node* aNode): current(aNode){};//constructor
        Iterator& operator=(const LinkedList::Iterator& aCopy) noexcept; //added this DELETE DUMMY?
        ~Iterator(); //dtor
        Iterator operator++();
        Iterator operator++(DataType);
        bool operator==(const Iterator &anIterator);
        bool operator!=(const Iterator &anIterator);
        DataType operator*();
        operator Node*();
        Node *current; //do I need to put LinkedList since it's a nested class?

      //add all the necessary operators

    protected:
    };

    //--------------------------------------------------------------

    LinkedList(); //default constructor...
    LinkedList(const LinkedList& aCopy); //copy ctor
    ~LinkedList(); //dtor
    LinkedList& operator=(const LinkedList& aCopy); //assignment operator

    void append(DataType value);
    void prepend(DataType value);
    void remove(DataType value);
    int size(); //needs to return unsigned int????
    Iterator begin();
    Iterator end();
    Iterator find(DataType aValue); //find



  protected:
  };

//class Iterator;
template <typename DataType> LinkedList<DataType>::LinkedList() {
      root=nullptr;
  }

template <typename DataType> LinkedList<DataType>::LinkedList(const LinkedList& aCopy){ //copy ctor
    Node *temp=aCopy.root;
    Node *newNode = new Node;
    root=newNode;

    while (temp != nullptr){
        newNode-> value=temp->value;
        temp=temp->next;
        if (temp !=nullptr){
            newNode->next=new Node;
            newNode=newNode->next;
        }
        else{ newNode->next=nullptr;}
    }
}

template <typename DataType> LinkedList<DataType>& template <typename DataType>LinkedList<DataType>::operator=(const LinkedList &aCopy){ //assignment operator
    while(root!=nullptr){
        Node* oneBefore= root;
        root =root->next;
        delete oneBefore;
    }
    Node *newNode= new Node;
    Node *temp=aCopy.root;
    root=newNode;

    while(temp!=nullptr){
        newNode->value=temp->value;
        temp=temp->next;
        if(temp!=nullptr){
            newNode->next=new Node;
            newNode=newNode->next;
        }
        else{newNode->next=nullptr;}
    }
    return *this;
}

LinkedList<DataType>::~LinkedList(){ //dtor
    Node* oneBefore = nullptr;
    while(root!=nullptr){
        oneBefore=root;
        root=root->next;
        delete oneBefore;
    }
}
LinkedList<DataType>::Iterator LinkedList::find(DataType aValue){
    Node* temp=root;
    Iterator myIterator = begin();
    for(myIterator = this->begin(); myIterator != this->end(); myIterator++){
        if(temp->value==aValue){
            return temp;
        }
        temp=temp->next;
    }
    return nullptr;
}

void LinkedList<DataType>::append(DataType value){
    Node* newNode=new Node;
    newNode->value=value;
    if(root!=nullptr){
        Node* temp = root;
        while (temp->next !=nullptr){
            temp=temp->next;
        }
        newNode->next=nullptr;
        temp->next=newNode;
    }
    if(root==nullptr){
        newNode->next=nullptr;
        root=newNode;
    }

}

void LinkedList<DataType>::prepend(DataType value){
    Node* newNode=new Node;
    newNode->value=value;
    if (root!=nullptr){
        newNode->next=root;
        root=newNode;
    }
    if(root==nullptr){
        root=newNode;
        newNode->next=nullptr;
    }
}

void LinkedList<DataType>::remove(DataType value){
    if(root!=nullptr){
        Node *before=nullptr;
        Node *temp=root;
        if(temp->value==value){
            root=temp->next;
        }
        else{
            while(temp->value!=value &&temp->next != nullptr){
                before=temp;
                temp=temp->next;
            }
            if(temp->value==value){
                before->next=temp->next;
            }
        }
        delete temp;
    }
}

int LinkedList<DataType>::size(){
    Node* aNode = root;
    int numElements=0;
    while(aNode!=nullptr){
        aNode=aNode->next;
        numElements=numElements+1;
    }
    return numElements;
}

LinkedList<DataType>::Iterator LinkedList::begin(){
    return LinkedList::Iterator(root);
}


LinkedList<DataType>::Iterator LinkedList::end(){
    Node *aNode=root;
    while(aNode!=nullptr){
        aNode=aNode->next;
    }
    return LinkedList::Iterator(aNode);
}

LinkedList<DataType>::Iterator::Iterator() : current(nullptr) {}

LinkedList<DataType>::Iterator::Iterator(Node* aNode): current(aNode){
};

template <typename DataType> typename LinkedList<DataType>::Iterator LinkedList<DataType>::Iterator::operator++(){//I have no idea what the difference is supposed to be between this one and the one below
    current=current->next;
    return *this;
}
template <typename DataType> typename LinkedList<DataType>::Iterator template<typename DataType> LinkedList<DataType>::Iterator::operator++(DataType){//I have no idea what the difference is supposed to be between this one and the one below
    current=current->next;
    return *this;
}

template <typename DataType> LinkedList<DataType>::Iterator& LinkedList::Iterator::operator=(const LinkedList::Iterator& aCopy) noexcept{ //assignment operator
    current=aCopy.current;
    return *this;
}

template <typename DatatType> bool LinkedList<DataType>::Iterator::operator !=(const LinkedList::Iterator& aCopy){
    return current != aCopy.current;
}

bool LinkedList<DataType>::Iterator::operator==(const LinkedList::Iterator& aCopy){
    return current==aCopy.current;
}

DataType LinkedList<DataType>::Iterator::operator*(){
    return current->value;
}

LinkedList<DataType>::Iterator::~Iterator(){}

1 Answers1

2

That's too many templates. You only need single template keyword for single definition:

template <typename DataType> // template specifier
LinkedList<DataType>& // return type
LinkedList<DataType>::operator= // name of function
(const LinkedList &aCopy) //arguments list
{ 
    //body
}

Typically, template keyword with template argument list is written in separate line, and then standard function definion (just as if there were no templates) follows:

template <typename DataType> 
typename LinkedList<DataType>::Iterator LinkedList<DataType>::Iterator::operator++(DataType){
    return *this;
}

Single template specifier affects the whole definion that follows it, so it can be used in anywhere in: return type, class scope specifier(LinkedList<DataType>::), function argument list and function body (assuming that it's the function definition that follows template).

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • Thanks so much! When I do that, I get the error "'LinkedList' is not a class, namespace, or enumeration" on the same line. Do you know what could be causing that? – sexytoasteroven Nov 13 '19 at 20:18
  • @sexytoasteroven I cannot reproduce the error which would say *'LinkedList' is not a class, namespace, or enumeration*. All errors I get from your code are from missing `template` before most methods implementation. https://wandbox.org/permlink/8rdxntybY0Sd8FI2 – Yksisarvinen Nov 13 '19 at 20:28
  • Strange! Thanks so much for all your help! I'll have to look more into this to see why I'm getting that then. Thanks again! – sexytoasteroven Nov 13 '19 at 20:34
  • @sexytoasteroven This could occur e.g. if you split the implementation into separate header and .cpp file and forgot to include header in .cpp file, but [you shouldn't do that](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Yksisarvinen Nov 13 '19 at 20:41
  • Hmmm, yeah, it's all in the header file, so I don't think it's that. – sexytoasteroven Nov 14 '19 at 01:43