Professional C__ - Marc Gregoire [310]
void hashmap 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 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(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 hashmap { 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 // Some compilers don't like make_pair here. pair 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 HashIterator 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 hashmap typename hashmap { // completely ignore hint return emplace(forward } 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 hashmap { size_t bucket; // First, try to find the element. auto it = findElement(x, bucket); if (it != (*mElems)[bucket].end()) { // The element exists--erase