Professional C__ - Marc Gregoire [303]
// support comparisons of different types to this one.
bool operator==(const HashIterator& rhs) const;
bool operator!=(const HashIterator& rhs) const;
protected:
size_t mBucket;
typename list const hashmap // Helper methods for operator++ and operator-- void increment(); void decrement(); }; Code snippet from Hashmap\FinalHashmap\hashmap.h If the definitions and implementations (shown in the next section) of the overloaded operators confuse you, consult Chapter 18 for details on operator overloading. The HashIterator Method Implementations The HashIterator constructors initialize the three member variables. The default constructor exists only so that clients can declare HashIterator variables without initializing them. An iterator constructed with the default constructor does not need to refer to any value, and attempting any operations on it is allowed to have undefined results: // Dereferencing or incrementing an iterator constructed with the // default ctor is undefined, so it doesn't matter what values we give // here. template HashIterator { mBucket = 0; mIt = list mHashmap = nullptr; } template HashIterator size_t bucket, typename list const hashmap mBucket(bucket), mIt(listIt), mHashmap(inHashmap) { } Code snippet from Hashmap\FinalHashmap\hashmap.cpp The implementations of the dereferencing operators are concise, but can be tricky. Chapter 18 explains that operator* and operator-> are asymmetric; operator* returns the actual underlying value, which in this case is the element to which the iterator refers, while operator-> must return something to which the arrow operator can be applied again. Thus, it returns a pointer to the element. The compiler then applies -> to the pointer, which will result in accessing a field of the element: // Return the actual element template pair { return *mIt; } // Return the iterator, so the compiler can apply -> to it to access // the actual desired field. template pair HashIterator { return &(*mIt); } Code snippet from Hashmap\FinalHashmap\hashmap.cpp The increment and decrement operators are implemented as follows, which defer the actual incrementing and decrementing procedures to the increment() and decrement() helper methods: // Defer the details to the increment() helper. template HashIterator HashIterator { increment(); return *this; } // Defer the details to the increment() helper. template const HashIterator HashIterator { auto oldIt = *this; increment(); return oldIt; } // Defer the details to the decrement() helper. template HashIterator HashIterator { decrement(); return *this; } // Defer the details to the decrement() helper. template const HashIterator HashIterator { auto oldIt = *this; decrement(); return oldIt; } Code snippet from Hashmap\FinalHashmap\hashmap.cpp Incrementing a HashIterator tells it to refer to the “next” element in the container. This