Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I call `delete` on a vector of pointers in C++ via for_each <algorithm>?

Suppose I have a std::vector<Obj *> objs (for performance reasons I have pointers not actual Objs).

I populate it with obj.push_back(new Obj(...)); repeatedly.

After I am done, I have to delete the pushed-back elements. One way is to do this:

for (std::vector<Obj *>::iterator it = objs.begin(); it != objs.end(); ++it) {
    delete *it;
}

However, I am interested if I can use for_each algorithm to do the same:

#include <algorithm>
...
for_each(objs.begin(), objs.end(), delete);

What do you think?

like image 993
bodacydo Avatar asked Nov 28 '22 01:11

bodacydo


2 Answers

Your problem is that delete is not a function, but rather a keyword and as such you can't take it's address.

In C++0x, there will be a std::default_delete class (used by std::unique_ptr), which you could use, or - as everyone's saying - writing one yourself would be trivial (the standard one also raises a compile error, if you try to delete an incomplete type).

#include <vector>
#include <algorithm>
#include <memory>

int main()
{
    std::vector<int*> vec;
    std::for_each(vec.begin(), vec.end(), std::default_delete<int>());
}
like image 106
UncleBens Avatar answered Feb 22 '23 23:02

UncleBens


Yes, but you need a functor:

struct delete_ptr
{
    template <typename T>
    void operator()(T* pPtr)
    {
        delete pPtr;
    }
};

std::for_each(objs.begin(), objs.end(), delete_ptr());

In C++0x, lambda's help you make functors in-place:

std::for_each(objs.begin(), objs.end(), [](Obj* pPtr){ delete pPtr; });

However, this is dangerous, in the face of exceptions. sbi has shown a solution.

like image 32
GManNickG Avatar answered Feb 22 '23 23:02

GManNickG