Putting together everything we've learned in this chapter, we can now write code like the following example. In this example, we're implementing our own list_of_ints with our own iterator class (including a const-correct const_iterator version); and we're enabling it to work with the standard library by providing the five all-important member typedefs.
struct list_node {
int data;
list_node *next;
};
template<bool Const>
class list_of_ints_iterator {
friend class list_of_ints;
friend class list_of_ints_iterator<!Const>;
using node_pointer = std::conditional_t<Const, const list_node*,
list_node*>;
node_pointer ptr_;
explicit list_of_ints_iterator(node_pointer p) : ptr_(p) {}
public:
// Member typedefs required by std::iterator_traits
using difference_type...