You need to create a function object:
struct second_deleter { template <typename T> void operator()(const T& pX) const { delete pX.second; } }; std::for_each(myMap.begin(), myMap.end(), second_deleter());
If you use boost, you can 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<myMap::value_type>(), _1));
But you can try the pointer container library that does this automatically.
Please note that you are not using a map, but hash_map . I recommend you switch to boost unordered_map , which is more relevant. However, ptr_unordered_map does not seem to exist.
For security reasons you should wrap this. For example:
template <typename T, typename Deleter> 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<int, Foo*>, second_deleter> my_container; my_container.container.
This ensures that no matter what, your container will be repeated using a deleter. (For exceptions, for example.)
For comparison:
std::vector<int*> v; v.push_back(new int); throw "leaks!";
GManNickG
source share