Online Book Reader

Home Category

Professional C__ - Marc Gregoire [309]

By Root 1364 0

hashmap::hashmap(initializer_list il,

const Compare& comp, const Hash& hash) throw(invalid_argument)

: mSize(0), mComp(comp), mHash(hash)

{

if (mHash.numBuckets() <= 0) {

throw invalid_argument("Number of buckets must be positive");

}

mElems = new vector(mHash.numBuckets());

insert(il.begin(), il.end());

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

With this initializer list constructor, a hashmap can be constructed in the following way:

hashmap myHash = {

{"KeyOne", 100},

{"KeyTwo", 200},

{"KeyThree", 300}};

This is much nicer than using insert() and make_pair() calls:

myHash.insert(make_pair("KeyOne", 100));

myHash.insert(make_pair("KeyTwo", 200));

myHash.insert(make_pair("KeyThree", 300));

hashmap Initializer List Assignment Operator

In C++11, assignment operators can also accept an initializer list on the right-hand side. Following is an implementation of an initializer list assignment operator for the hashmap. It deletes all the elements from the hashmap and then delegates the work to the insert() method accepting an iterator range:

template

hashmap& hashmap::operator=(

initializer_list il)

{

clear();

insert(il.begin(), il.end());

return *this;

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

With this assignment operator, you can write code as follows:

myHash = {

{"KeyOne", 100},

{"KeyTwo", 200},

{"KeyThree", 300}};

hashmap Insertion Operations

In the basic hashmap section earlier in this chapter, a simple insert() method was given. In this version, four insert() versions are provided with additional features:

The simple insert() operation returns a pair, which indicates both where the item is inserted and whether or not it was newly-created.

The version of insert() that takes a position is useless for a hashmap, but it is provided for symmetry with other kinds of collections. The position is ignored, and it merely calls the first version.

The third form of insert() is a method template, so it can be used by algorithms that work on arbitrary containers.

The last form of insert() accepts an initializer_list.

The first two insert() methods are implemented as follows:

template

pair::iterator, bool>

hashmap::insert(const value_type& x)

{

size_t bucket;

// Try to find the element.

auto it = findElement(x.first, bucket);

if (it != (*mElems)[bucket].end()) {

// The element already exists.

// Convert the list iterator into a HashIterator, which

// also requires the bucket and a pointer to the hashmap.

HashIterator newIt(bucket, it, this);

// Some compilers don't like make_pair here.

pair, bool> p(newIt, false);

return p;

} else {

// We didn't find the element, so insert a new one.

mSize++;

auto endIt = (*mElems)[bucket].insert((*mElems)[bucket].end(), x);

pair, bool> p(

HashIterator(bucket, endIt, this), true);

return p;

}

}

template

typename hashmap::iterator

hashmap::insert(typename hashmapHash>::iterator position, const value_type& x)

{

// Completely ignore position

return insert(x).first;

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

The third form of insert() is a method template for the same reason as the constructor shown earlier: It should be able to insert elements by using iterators from containers of any type. The actual implementation uses an insert_iterator, which is described earlier in this chapter:

template

template

Return Main Page Previous Page Next Page

®Online Book Reader