0

I get an error and I don't know why. Throughout the code the line Node * curr = head works just fine and no problems whatsoever, but when I try to overload the << operator it suddenly tells me that head should be static. Why? And when I make him static nothing else works because it says that the head is undefined.. In addition, when I try to call cout << something with the overloaded operator it does not compile and returns more errors. How can I fix this? This is my code:

#include <iostream>
#include <cstring>
#include <string>
#include <functional>

#include "dummy.h"
using namespace std;

#ifndef SORT_H
#define SORT_H

template <typename T>
class LinkedList {
    class Node {
        T data;
        Node *next;

        friend class LinkedList; // make LinkedList class methods can to access Node information
    };

    Node *CreateNode(T data) {
        // allocates a new node with
        // given data and returns it
        Node *pNewNode = new Node;
        pNewNode->data = data;
        pNewNode->next = nullptr;

        return pNewNode;
    }

    Node *&GetHead() {
        // Return list head by reference
        return head;
    }

    Node *head;

public:

    class const_iterator {
        // Iterator class
    private:
        const Node *curr_node;

    public:
        const_iterator() :
                curr_node(head) {}

        const_iterator(const Node *node) :
                curr_node(node) {}

        const_iterator &operator=(Node *node) {
            this->curr_node = node;
            return *this;
        }

        const_iterator &operator++() {
            if (curr_node != nullptr){
                curr_node = curr_node->next;
            }
            return *this;
        }

        const_iterator operator++(int) {
            const_iterator const_iterator = *this;
            ++*this;
            return const_iterator;
        }

        bool operator!=(const const_iterator &const_iterator) {
            return curr_node != const_iterator.curr_node;
        }

        T operator*() {
            return curr_node->data;
        }

        friend ostream& operator << (ostream& output, const_iterator it)
        {
            Node * curr = head;
            while (curr) {
                if (curr -> data == *it) {
                    output << curr -> data << endl;
                    curr = curr -> next;
                }
            }
            return output;
        }

    };

    LinkedList() {
        head = nullptr;
    }
    LinkedList(T value) {
        head = new Node(value);
        head -> data = value;
        head -> next = nullptr;
    }

    ~LinkedList() {
        while(head != nullptr) {
            Node * curr = head -> next;
            delete head;
            head = curr;
        }
    }

    bool is_in_list(const_iterator it){
        Node * curr = head;
        while(curr != nullptr) {
            if (curr->data == *it){
                return true;
            } else {
                curr = curr->next;
            }
        }
        return false;
    }

    LinkedList& operator = (LinkedList list) {
        std::swap(list.head, head);
        return *this;
    }

    Node * nodeCopy(Node * head) {
        if (head == nullptr) {
            return nullptr;
        }
        Node * copied_node = CreateNode(head -> data);
        copied_node -> data = head -> data;
        copied_node -> next = nodeCopy(head -> next);
        return copied_node;
    }

    LinkedList(const LinkedList &list){
        head = nodeCopy(list.head);
    }

    template<typename B>
    LinkedList filter(B pred) {
        LinkedList <T> new_list;
        Node * curr = head;
        while (curr) {
            if (pred(curr -> data)) {
                new_list.insert(curr -> data);
            }
            curr = curr -> next;
        }
        std::cout << "Getting out of filter" << std::endl;
        return new_list;
    }

    template<typename A>
    LinkedList apply(A func) {
        LinkedList <T> new_list;
        Node * curr = head;
        while (curr) {
            new_list.insert(func(curr -> data));
            std::cout << "Putting into new list: " << func(curr -> data) << std::endl;
            curr = curr -> next;
        }
        std::cout << "Getting out of apply" << std::endl;
        return new_list;
    }

    int length() {
//        std::cout << "DEBUG length 1" << std::endl;
        int counter = 0;
        Node * tmp = head;
//        std::cout << "DEBUG length 2" << std::endl;
        while( tmp != nullptr ) {
//            std::cout << "DEBUG length 3" << std::endl;
            counter++;
            tmp = tmp -> next;
        }
        return counter;
    }

    void insert(T data) {
// Add first node
        if (head == nullptr) {
            std::cout << "Add first node" << std::endl;
            head = CreateNode(data);
            head->next = nullptr;
            return;
        }

        Node *curr = head;
        // check if should be new head (when new value smaller than current head) -> add new head
        if (data <= head->data) {
            // add new head
            // std::cout << "add new head" << std::endl;
            Node * new_head = CreateNode(data);
            new_head -> next = head;
            head = new_head;
            return;
        }

        while (curr != nullptr) {
            if (curr->next == nullptr && data >= curr->data) {
                // add new tail
                // std::cout << "add new tail" << std::endl;
                Node * new_node = CreateNode(data);
                curr -> next = new_node;
                new_node -> next = nullptr;
                return;
            } else if (data >= curr->data && data <= curr->next->data) {
                // add new node between those two
                // std::cout << "add new node between those two" << std::endl;
                Node * new_node = CreateNode(data);
                Node * temp_ptr = curr -> next;
                curr -> next = new_node;
                new_node -> next = temp_ptr;
                return;
            } else {
                curr = curr->next;
            }
        }
    }

    void remove(const_iterator it) {
        // TODO: Check if delete all accurancies
        if (!is_in_list(it)){
            return;
        }

        // handle the head
        if (head -> data == *it) {
            if (head->next != nullptr) {
                // head is not single node
                Node * temp_ptr = head->next;
                delete head;
                head = temp_ptr;
                return;
            } else {
                // head is single node
                delete head;
                head = nullptr;
                return;
            }
        }

        Node * curr = head;
        Node * prev = head;
        while (curr != nullptr){
            if (curr -> data == *it){
                // as we are already handled the head case,
                // at this point we know that curr != head.
                prev->next = curr->next;
                delete curr;
                return;
            } else {
                prev=curr;
                curr=curr->next;
            }
        }

    }

    void print() {
        Node * curr = head;
        while (curr != nullptr) {
            cout << curr -> data << endl;
            curr = curr -> next;
        }
    }

    Node* begin() const {
        return head;
    }

    Node* end() const {
        Node * curr = head;
        while (curr->next != nullptr){
            curr = curr->next;
        }
        return curr;
    }
};


#endif

And the main:

#include <iostream>
#include "sortedList.h"
#include "dummy.h"

bool func(Dummy num) {
    int number = num.get();
    if (number % 2 != 0) {
        return false;
    }
    return true;
}

string getLen(string str)
{
    return std::to_string(str.length());
}

using std::string;

template<class T>
void printList(LinkedList<T> list) {
    for (auto it = list.begin(); !(it == list.end()); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

int main() {
    std::cout << "Hello, World!" << std::endl;

        LinkedList<string> lst1 = LinkedList<string>();
        lst1.insert("Charlie");
        lst1.insert("Bob");
        lst1.insert("Alice");
        lst1.insert("Donald");
        printList(lst1);
        LinkedList<string> lst2 = lst1;
        lst2 = lst2.apply(getLen);
        printList(lst2);
        LinkedList<string>::const_iterator it = lst2.begin();
        cout << *it << endl << endl;
        ++it;
        lst2.remove(it);
        printList(lst2);

    return 0;
}

The errors look like:

In file included from C:\Users\User\CLionProjects\ex2.2\main.cpp:2:
C:\Users\User\CLionProjects\ex2.2\sortedList.h: In function 'std::ostream& operator<<(std::ostream&, LinkedList<T>::const_iterator)':
C:\Users\User\CLionProjects\ex2.2\sortedList.h:80:27: error: invalid use of non-static data member 'LinkedList<T>::head'
             Node * curr = head;
                           ^~~~
C:\Users\User\CLionProjects\ex2.2\sortedList.h:36:11: note: declared here
     Node *head;
           ^~~~
C:\Users\User\CLionProjects\ex2.2\main.cpp: In instantiation of 'void printList(LinkedList<T>) [with T = std::__cxx11::basic_string<char>]':
C:\Users\User\CLionProjects\ex2.2\main.cpp:36:23:   required from here
C:\Users\User\CLionProjects\ex2.2\main.cpp:23:14: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'LinkedList<std::__cxx11::basic_string<char> >::Node')
         cout << *it << endl;
         ~~~~~^~~~~~
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iostream:39,
                 from C:\Users\User\CLionProjects\ex2.2\main.cpp:1:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ostream:108:7: note: candidate: 'std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]'
       operator<<(__ostream_type& (*__pf)(__ostream_type&))
SpaceNugget
  • 105
  • 7

0 Answers0