1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
/*
The way to remove elements from a hash_map isn't intuitively obsious:
a for_each construction can't be used, as the erase() during the for_each
fucks up the for_each process.
This also holds true for other gerneric algorithms in which iterators are
used, like remove_if etc.
The problem is probably caused by the fact that the keys in a hash_map
aren't ordered, and therefore reordering keys isn't a well defined
operation.
the approach taken here is to collect the relevant keys in a set, and then
iterate over the set of keys, removing the corresponding elements from the
hash_map
*/
#include <algorithm>
#include <iostream>
#include <hash_map>
#include <set>
class Eraser
{
public:
Eraser(set <char const *> &keys)
:
keys(keys)
{}
void operator()(pair<char const *, int> const &it)
{
if (*it.first == 'a' || *it.first == 'e')
keys.insert(set<char const *>::value_type(it.first));
}
private:
set<char const *>
&keys;
};
class Remove
{
public:
Remove(hash_map <char const *, int> &hm)
:
hm(hm)
{}
void operator()(char const *cp)
{
hm.erase(cp);
}
private:
hash_map<char const *, int>
&hm;
};
class List
{
public:
bool operator()(pair<char const *, int> const &it)
{
cerr << it.first << " = " << it.second << '\n';
return true;
}
};
int main(int argc, char **argv)
{
hash_map<char const *, int>
hm;
hm["a"] = 1;
hm["b"] = 2;
hm["c"] = 3;
hm["d"] = 4;
hm["e"] = 5;
hm["f"] = 6;
hm["g"] = 7;
hm["h"] = 8;
set<char const *> keys;
for_each(hm.begin(), hm.end(), Eraser(keys));
for_each(keys.begin(), keys.end(), Remove(hm));
for_each(hm.begin(), hm.end(), List());
}
|