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&))