Reputation: 10971
The following code raises a runtime error:
#include <iostream>
#include <iterator>
#include <ext/slist>
class IntList : public __gnu_cxx::slist<int> {
public:
IntList() { tail_ = begin(); } // seems that there is a problem here
void append(const int node) { tail_ = insert_after(tail_, node); }
private:
iterator tail_;
};
int main() {
IntList list;
list.append(1);
list.append(2);
list.append(3);
for (IntList::iterator i = list.begin(); i != list.end(); ++i) {
std::cout << *i << " ";
}
return 0;
}
Seems that the problem is in the constructor IntList()
. Is it because it calls the member function begin()
?
Upvotes: 4
Views: 9731
Reputation: 58715
Your problem is not in the constructor but in the first call to append()
. Because your list is empty begin()
equals end()
. end()
is a valid iterator, but the one after that isn't. To solve that particular problem try calling insert()
instead.
That said, a fast peek at <ext/slist>
confirms that the destructor of slist
isn't virtual, which means slist
wasn't intended to be derived from.
Upvotes: 1
Reputation: 264649
The documentation for slist<> indicates that the iterator provided to insert_after must be dereferenceable.
Since your list is empty the begin() returns end() and is thus not dereferenceable.
See documentation here:
http://www.sgi.com/tech/stl/Slist.html
iterator insert_after(iterator pos, const value_type& x)
pos must be a dereferenceable iterator in *this. (That is, pos may not be end().) Inserts a copy of x immediately following pos. The return value is an iterator that points to the new element. Complexity: constant time.
Upvotes: 2
Reputation: 7995
Looks like You are inserting after end();
In the body of the constructor
IntList() { tail_ = begin(); }
the base class is constructed and it's members can be called, but for an empty list, it should return end();
Upvotes: 2