假设我有一个STL地图,该值是指针,我想将它们全部删除。我如何将代表下面的代码,但利用的std :: for_each的吗?我很高兴的解决方案,使用升压。
for( stdext::hash_map<int, Foo *>::iterator ir = myMap.begin();
ir != myMap.end();
++ir )
{
delete ir->second; // delete all the (Foo *) values.
}
(我发现Boost的checked_delete
,但我不知道如何应用到迭代器代表pair<int, Foo *>
)。
(另外,对于这个问题的目的,忽视的事实是存储需要在STL容器删除原始指针不是非常明智的)。
注:我后来发现下面列出的一个单行的答案...但代码是很可怕,所以我已经接受GMAN的理智的答案。
你必须做一个函数对象:
struct second_deleter
{
template <typename T>
void operator()(const T& pX) const
{
delete pX.second;
}
};
std::for_each(myMap.begin(), myMap.end(), second_deleter());
如果您使用的提升,你也可以使用λ文库:
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));
但是你可以尝试pointer containers库,自动执行此操作。
请注意,您使用的不是地图,而是一个hash_map
。我建议您切换到升压转换器的unordered_map
,这是更大的电流。然而,似乎没有成为一个ptr_unordered_map
。
为了安全,你应该穿得这件事情了。例如:
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;
};
并使用它,如:
typedef wrapped_container<
boost::unordered_map<int, Foo*>, second_deleter> my_container;
my_container.container./* ... */
这确保不管是什么,你的容器将通过与有删除重复。 (有关例外,例如)。
相比:
std::vector<int*> v;
v.push_back(new int);
throw "leaks!"; // nothing in vector is deleted
wrapped_container<std::vector<int*> > v;
v.container.push_back(new int);
throw "no leaks!"; // wrapped_container destructs, deletes elements
你是否尝试过使用BOOST_FOREACH?这应该允许你这样做,在一个行而不创建自己的仿函数。
我没有测试过下面的代码,但它应该是这个样子(即使不完全):
typedef stdext::hash_map<int, Foo *> MyMapType; //see comment.
BOOST_FOREACH( MyMapType::value_type& p, myMap )
{
delete p.second;
}
那么这就是超过1线,由于typedef的:)
好吧,我发现了如何做到这一点的一条线......但我不认为我会永远实际上做下面的实际代码!
std::for_each( mayMap.begin()
, myMap.end()
, boost::bind( &boost::checked_delete<Foo>
, boost::bind( &stdext::hash_map<int, Foo *>::value_type::second, _1 ) ) );
不过我会接受GMAN的答案,因为我喜欢他的一包装的容器的想法,我的答案,尽管是作为请求一行,只是普通的讨厌。
如果可能的话,你应该在你的地图使用智能指针。
使用智能指针的位置,就不再需要重构和调试成员删除。少了一个内存管理操心前进。任何时候,我用新/删除我觉得真的很难了解这是否是必要的。个人的“代码味道”(每Martin Fowler的),如果你喜欢。
当然,如果你的旧代码返回一个地图,那么for_each
的方法可能是你最好的选择 - 但如果你有一些携手创建地图,我推荐使用智能指针。