You could introduce a sentinel node and have a circular linked list.
A sketch:
class List
{
private:
struct Node {
Node* previous;
Node* next;
Node() : previous(this), next(this) {}
};
struct DataNode : Node {
int data;
};
public:
class iterator
{
friend class List;
private:
iterator(Node* node) : m_node(node) {}
public:
iterator() : m_node(0) {}
iterator& operator ++() {
m_node = m_node->next;
return *this;
}
int& operator * () {
// Note: Dereferncing the end (sentinal node) is undefined behavior.
return reinterpret_cast<DataNode*>(m_node)->data;
}
// More iterator functions.
private:
Node* m_node;
};
public:
List() : m_sentinal(new Node) {}
iterator begin() { return iterator(m_sentinal->next); }
iterator end() { return iterator(m_sentinal); }
iterator insert(iterator position, int data) {
DataNode* data_node = new DataNode; // pass data
Node* current = position.m_node;
data_node->next = current;
data_node->previous = current->previous;
current->previous->next = data_node;
current->previous = data_node;
return iterator(current);
}
void append(int data) {
insert(end(), data);
}
private:
Node* m_sentinal;
};