error pointer operand

I get this error when I try compiling my code is there a way I can fix this.

testings.cpp:69:48: error: indirection requires pointer operand
('List<char>::It' invalid)
for (; begin != end; ++begin) this->Insert(*begin);
^~~~~~
testings.cpp:114:12: note: in instantiation of function template specialization
'List<char>::List<List<char>::It>' requested here
List<char> first (test.begin(), test.end());
^
testings.cpp:94:13: warning: expression result unused [-Wunused-value]
this->cur;
~~~~ ^~~
testings.cpp:69:26: note: in instantiation of member function
'List<char>::It::operator++' requested here
for (; begin != end; ++begin) this->Insert(*begin);
^
testings.cpp:114:12: note: in instantiation of function template specialization
'List<char>::List<List<char>::It>' requested here
List<char> first (test.begin(), test.end());
^
1 warning and 1 error generated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <initializer_list>
#include <iostream>

template <typename T>
class List {
  struct Node;  
  class It;
 public:
  List() {
    std::initializer_list<T> empty;
  }

  List(std::initializer_list<T> ele) {
    this->operator=(ele);  
  }

std::size_t Size() const {
    int count = 0;
    Node* current = start;
    while (current != NULL) {
      count++;
      current = current->next;
    }
    return count;
  }

  void Insert(T ele) {
    Node* node = new Node{ele};
    if (this->size == 0) {
      this->start = this->fin = node;
    } else {
      this->fin->next = node;
      node->prev = this->fin;
      this->fin = node;
    }
    ++this->size;
  }

  void RemoveFront() {
    Node* front = this->start;
    this->start = front->next;
    delete front; 
  }

  T& Front() const {
     if (Size() <= 0) {
       return Front();
     }
    Node* Front = start;
    return Front->data;
  }

  List& operator=(std::initializer_list<T> ele) {
    this->size = 0;
    for (auto&& val : ele) this->Insert(val);
    return *this;
  }

  friend std::ostream& operator<<(std::ostream& out, const List& list) {
    for (auto val = list.start; val; val = val->next) {
      out << val->data;
      if (val->next) out << ",";
    }
    return out;
  }

  template <class It>
  List(It begin, It end) {
    for (; begin != end; ++begin) this->Insert(*begin);
  }

  It begin() {
    return It(start);
  }

  It end() {
    return It(fin);
  }

private:
  struct Node {
    T data;
    Node* next = nullptr;
    Node* prev = nullptr;
  };

  class It {
    friend class List;
    explicit It (List::Node *ptr) : cur(ptr) {}
     typename List<T>::Node* cur;
    List<T>* theList;
    public:
    It& operator++() {
      this->cur;
      return *this;
    }
    It operator++(int) {
      It temp(*this);
      this->operator++();
      return temp;
    }
     bool operator!=(It val) const { 
       return !(this->operator==(val));
     }
     bool operator==(It val) const { 
       return !(this->operator!=(val));
     }
  };

  Node* start = nullptr;
  Node* fin = nullptr;
  std::size_t size = 0;
};

int main() {
List<char> test = {'H', 'e', 'l', 'l', 'o'};
std::cout << test << std::endl;
List<char> first (test.begin(), test.end());
}
Last edited on
Don't return a reference, just return It.

You haven't defined operator!= for your iterators. (Although you might find that setting your end iterators internal pointer to "fin" is not going to work too well.)

Your Size method actually counts the nodes in the list, even though you have a size member that you could return (as long as you update it properly; for instance, RemoveFront should subtract 1 from it.).

Your default ctor has a pointless initializer_list in it.
1
2
3
It& begin() {
    return It(start);
}


In this function, the expression It(start) is a temporary object. The language refuses to take a (non-const lvalue) reference to it, because the referent would be destroyed immediately at the semicolon of the return statement.

You don't want to return a reference to a temporary value at all: just return by value:
1
2
3
It begin() {
    return It(start);
}


Same advice for end().

Then, your problem is that you never implemented operator overloads for List::It.
You also have never provided a suitable constructor for List::Node.
Last edited on
So I edited the code and added what you specified and the new operators but now I get this new error and also how could I rewrite my operator++() so it moves through each iterator?
Which new error?

Sorry @tpb, I didn't see your post until now.
I redid the post n edited the code and posted the new error now I get just one error also I'm wondering if there is a way to change the operator++() so it moves through each iterator or the the next one.
You need to add a dereference operator (and indirect member access) for It, these will do:
1
2
3
4
5
T const *operator->() const { return &(**this); }
T *operator->() { return &(**this); }
    
T& operator*() const { return this->cur->data; }
T const &operator*() { return this->cur->data; }

Although this is a bit confusing because List::It is overly complicated.

These functions never return; they call each other for ever. You have to actually write at least one of them:
1
2
3
4
5
6
bool operator!=(It val) const { 
  return !(this->operator==(val));
}
bool operator==(It val) const {
  return !(this->operator!=(val));
}

It is generally easier to understand conditions that aren't inverted, so we'll prefer to write == and leave != like it is:
This one will do:
1
2
3
bool operator==(It val) const { 
  return this->cur == val->cur; 
}


This is enough to get the code to compile: see
http://coliru.stacked-crooked.com/a/dc3c05c3e8d61188

And some advice:

The key to fixing an incorrect program is to attack problems one at a time. Because new code is always broken, it's absolute madness to continually pile new untested code atop broken components in the hope of fixing everything later.

Test your code continually, piece-by-piece as you write it; fix visible errors as you make them.
Last edited on
thanks I got it too work also
I redid the post n edited the code

Please DON'T do that. It makes the thread impossible to understand for anyone coming to it fresh, and makes it useless as a learning resource for others.
Topic archived. No new replies allowed.