Online Book Reader

Home Category

Professional C__ - Marc Gregoire [305]

By Root 1471 0
T, typename Compare, typename Hash>

bool HashIterator::operator!=(

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 iterator;

typedef HashIterator const_iterator;

// 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::iterator

hashmap::begin()

{

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(i,

(*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::iterator

hashmap::end()

{

// The end iterator is just the end iterator of the list in last bucket.

return HashIterator(mElems->size() - 1,

(*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::const_iterator

hashmap::cbegin() const

{

return const_cast*>(this)->begin();

}

template

typename hashmap::const_iterator

hashmap::cend() const

{

return const_cast*>(this)->end();

}

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;

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 " <<

Return Main Page Previous Page Next Page

®Online Book Reader