Online Book Reader

Home Category

Professional C__ - Marc Gregoire [310]

By Root 1381 0

void hashmap::insert(InputIterator first,

InputIterator last)

{

// Copy each element in the range by using an insert_iterator

// adapter. Give begin() as a dummy position--insert ignores it

// anyway.

insert_iterator> inserter(*this, begin());

copy(first, last, inserter);

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

In C++11, you should implement an insert operation that accepts an initializer list, discussed in Chapter 9. The implementation for the hashmap is very straightforward and forwards the work to the insert() method accepting an iterator range:

template

void hashmap::insert(initializer_list il)

{

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

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

With this insert() method, you can write code as follows:

myHash.insert({

{"KeyFour", 400},

{"KeyFive", 500}});

hashmap Emplace Operations

Emplace operations construct objects in place using the rvalue reference feature and are new to C++11. They are discussed in Chapter 12. Their implementation is straightforward in this case because we can forward the emplace operation to the correct bucket list. The emplace() method is implemented exactly the same as the corresponding insert() method, except that it calls emplace() on the list instead of insert():

template

pair::iterator, bool>

hashmap::emplace(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 emplace a new one.

mSize++;

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

pair, bool> p(

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

return p;

}

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

The emplace_hint() method ignores the hint and forwards the call to the emplace() method. This implementation uses std::forward to forward x as an rvalue reference to the emplace() method. This is required, because a named variable, x, will normally be treated as an lvalue reference, but in this case, you want it to be treated as an rvalue reference:

template

typename hashmap::iterator

hashmap::emplace_hint(

typename hashmap::iterator hint, value_type&& x)

{

// completely ignore hint

return emplace(forward(x)).first;

}

Code snippet from Hashmap\FinalHashmap\hashmap.cpp

hashmap Erase Operations

The version of erase() in the earlier section “A Basic Hashmap” is not compliant with STL requirements. You need to implement the following versions:

A version that takes as a parameter a key_type and returns a size_type for the number of elements removed from the collection (for the hashmap, there are only two possible return values, 0 and 1)

A version that erases a value at a specific iterator position, as indicated by a HashIterator, and returns void

A version that erases a range of elements, based on two iterators, and returns void

The first version is implemented as follows:

template

typename hashmap::size_type

hashmap::erase(const key_type& x)

{

size_t bucket;

// First, try to find the element.

auto it = findElement(x, bucket);

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

// The element exists--erase

Return Main Page Previous Page Next Page

®Online Book Reader