Some STL algorithms need to know the characteristics of the iterator type they are used with. Some others need to know the type of items the iterators iterate over. This has different implementation reasons.
However, all STL algorithms will access this type information via std::iterator_traits<my_iterator>, assuming that the iterator type is my_iterator. This traits class contains up to five different type member definitions:
- difference_type: What type results from writing it1 - it2?
- value_type: Of what type is the item which we access with *it (note that this is void for pure output iterators)?
- pointer: Of what type must a pointer be in order to point to an item?
- reference: Of what type must a reference be in order to reference an item?
- iterator_category: Which category does the iterator belong to?
The pointer, reference, and difference_type type definitions do not make sense for our num_iterator, as it doesn't iterate over real memory values (we just return int values but they are not persistently available like in an array). Therefore it's better to not define them because if an algorithm depends on those items being referenceable in memory, it might be buggy when combined with our iterator.