Professional C__ - Marc Gregoire [305]
bool HashIterator const HashIterator& rhs) const { return !(*this == rhs); } Code snippet from Hashmap\FinalHashmap\hashmap.cpp const Iterators Technically, you should provide both an iterator and a const iterator for your hashmap class. The const iterator should function like the iterator, but should provide read-only access to the elements. The iterator should always be convertible to a const iterator. We omit the details of the const iterator and leave its implementation as an exercise for the reader. Iterator typedefs and Access Methods The final piece involved in providing iterator support for the hashmap is to supply the necessary typedefs in the hashmap class definition and to write the begin() and end() methods and the C++11 cbegin() and cend() methods on the hashmap. The typedefs and method prototypes look like this: template typename Hash = DefaultHash class hashmap { public: // Other typedefs omitted for brevity typedef HashIterator typedef HashIterator // Iterator methods iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; const_iterator cbegin() const; // For C++11 const_iterator cend() const; // For C++11 // Remainder of class definition omitted for brevity }; Code snippet from Hashmap\FinalHashmap\hashmap.h The trickiest aspect of begin() is to remember to return the end iterator if there are no elements in the container: template typename hashmap hashmap { if (mSize == 0) { // Special case: there are no elements, so return the end iterator return end(); } // We know there is at least one element. Find the first element. for (size_t i = 0; i < mElems->size(); ++i) { if (!((*mElems)[i].empty())) { return HashIterator (*mElems)[i].begin(), this); } } // Should never reach here, but if we do, return the end iterator return end(); } Code snippet from Hashmap\FinalHashmap\hashmap.cpp end() creates a HashIterator referring to the end iterator of the last bucket: template typename hashmap hashmap { // The end iterator is just the end iterator of the list in last bucket. return HashIterator (*mElems)[mElems->size() - 1].end(), this); } Code snippet from Hashmap\FinalHashmap\hashmap.cpp Because we don’t provide a const_iterator, the implementation of the const versions of begin() and end() are identical to the non-const versions of begin() and end(). The C++11 cbegin() and cend() methods forward the call to the const versions of begin() and end(): template typename hashmap hashmap { return const_cast } template typename hashmap hashmap { return const_cast } Code snippet from Hashmap\FinalHashmap\hashmap.cpp Using the HashIterator Now that the hashmap supports iteration, you can iterate over its elements just as you would on any STL container, and you can pass the iterators to methods and functions: hashmap myHash.insert(make_pair("KeyOne", 100)); myHash.insert(make_pair("KeyTwo", 200)); myHash.insert(make_pair("KeyThree", 300)); for (auto it = myHash.cbegin(); it != myHash.cend(); ++it) { // Use both -> and * to test the operations. cout << it->first << " maps to " <<