Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete any container using templates

I have a lot of code where I am deleting vector containers that have pointers in them, that is, I have to delete all the pointers first and then clear the container. Every time I would iterate through and delete the pointers manually (I am aware of stl::algorithms for_each). To circumvent all that code, I created a template for deleting all vector containers that have a pointer. So far so good.

Now I have several more container types including maps, concurrent containers etc. all with the same functionality in the end as far as deletion goes. The DeleteContainer(std::vector<T*>& VecIn) function that I have can only work on vectors as mentioned above. Is there any way to make it generic enough to work on all containers?

EDIT: Thanks for all the answers, I wish I could select more than one. To anybody who stumbles onto this question, read all the answers and not just the selected one as they all provide great info.

like image 344
Samaursa Avatar asked Dec 18 '10 18:12

Samaursa


4 Answers

You already have a valid answer, but just to provide an alternative, I believe you should consider using Boost Pointer Container and let it handle memory management :

This library therefore provides standard-like containers that are for storing heap-allocated or cloned objects (or in case of a map, the mapped object must be a heap-allocated or cloned object). For each of the standard containers there is a pointer container equivalent that takes ownership of the objects in an exception safe manner.

like image 144
icecrime Avatar answered Oct 30 '22 00:10

icecrime


You could use boost pointer containers.
They hold maintain and delete pointers correctly.

http://www.boost.org/doc/libs/1_38_0/libs/ptr_container/doc/reference.html

{
    boost::ptr_vector<int>   data;

    data.push_back(new int(2));
    data.push_back(new int(2));
    data.push_back(new int(2));
}
// container deleted and all pointers correctly destroyed.
like image 21
Martin York Avatar answered Oct 30 '22 00:10

Martin York


I'll second many people and avise using shared_ptr or boost pointer containers. However, you can write

template <typename Iter>  
void delete_pointers(Iter begin, Iter end)
{
    for (; begin != end; ++begin) delete *begin;
}

Usage:

std::vector<Foo*> v;

// Initialize Foo objects

delete_pointers(v.rbegin(), v.rend());

I use rbegin and rend instead of begin and end because sometimes, people want objects to be deleted in the reverse order they were created.

You can also do

void destroyFoo(Foo* x) { delete x; }

std::for_each(v.rbegin(), v.rend(), &destroyFoo);

or use C++0x lambdas.

like image 4
Alexandre C. Avatar answered Oct 30 '22 00:10

Alexandre C.


You can just use boost::shared_ptr<T> insted of T* and there will not be reason of DeleteContainer. But If you don't want to do this, you can make something like this

template<class T>
void DeleteContainer(typename T::iterator begin, typename T::iterator end)
{
 for(;begin!=end;++begin)
  delete *begin;
}

then you can just call it for any stl container you want in this way:

std::some_container<int*> s;
DeleteContainer<std::some_container<int*> > (s.begin(), s.end());
like image 3
Mihran Hovsepyan Avatar answered Oct 30 '22 00:10

Mihran Hovsepyan