Suppose I have a STL map where the values are pointers, and I want to delete them all. How would I represent the following code, but making use of std::for_each? I\'m happy for
You have to make a function object:
struct second_deleter
{
template
void operator()(const T& pX) const
{
delete pX.second;
}
};
std::for_each(myMap.begin(), myMap.end(), second_deleter());
If you're using boost, you could also use the lambda library:
namespace bl = boost::lambda;
std::for_each(myMap.begin(), myMap.end(), second_deleter(),
bl::bind(bl::delete_ptr(),
bl::bind(std::select2nd(), _1));
But you might try the pointer containers library which does this automatically.
Note you are not using a map, but a hash_map
. I recommend you switch to boost's unordered_map
, which is more current. However, there doesn't seem to be a ptr_unordered_map
.
For safety, you should wrap this thing up. For example:
template
struct wrapped_container
{
typedef T container_type;
typedef Deleter deleter_type;
wrapped_container(const T& pContainer) :
container(pContainer)
{}
~wrapped_container(void)
{
std::for_each(container.begin(), container.end(), deleter_type());
}
T container;
};
And use it like:
typedef wrapped_container<
boost::unordered_map, second_deleter> my_container;
my_container.container./* ... */
This ensures no matter what, your container will be iterated through with a deleter. (For exceptions, for example.)
Compare:
std::vector v;
v.push_back(new int);
throw "leaks!"; // nothing in vector is deleted
wrapped_container > v;
v.container.push_back(new int);
throw "no leaks!"; // wrapped_container destructs, deletes elements