boost::checked_deleter and std::map

Started by
7 comments, last by LizardCPP 16 years, 4 months ago
Hey To remove all elements from a std::vector i do the following

vector<Object*> objects;

// deleting
for_each(objects.begin(), objects.end(), boost::checked_deleter<Object>());
objects.clear();


But how do I make this work for more complexed cases as a std::map? Currently I have this, that works for std::map since it uses a std::pair internally:

template<class K, class V> 
struct checked_deleter_pair
{
	void operator()(std::pair<K, V*> x) const
	{
		boost::checked_delete(x.second);
	}
};


But this is hard coded for a std container that contains a std::pair, are there a way to do this more generally? Lizard
Advertisement
Just use a smart pointer. Then the cleanup becomes just using the container's destructor. Can't get very much more general than that.
Quote:Original post by SiCrane
Just use a smart pointer. Then the cleanup becomes just using the container's destructor. Can't get very much more general than that.


Yeah I should probably just do that. I was just thinking that I could forward declare the pointer type, which I can't if I use shared_ptr.

Thanks

Lizard

Quote:Original post by LizardCPP
Yeah I should probably just do that. I was just thinking that I could forward declare the pointer type, which I can't if I use shared_ptr.

Sure you can. On any modern compiler, anyway.
Quote:Original post by Sneftel
Quote:Original post by LizardCPP
Yeah I should probably just do that. I was just thinking that I could forward declare the pointer type, which I can't if I use shared_ptr.

Sure you can. On any modern compiler, anyway.


Feeling a bit embarrassed now.

It was a line like this:
map<int, shared_ptr<Object> > objects;

that I thought would never work to forward declare, since its declared as Object and not Object*.

But I tried it out and yeah it compiled.

Thanks

Lizard
Quote:Original post by LizardCPP
I was just thinking that I could forward declare the pointer type, which I can't if I use shared_ptr.
#ifndef ENTITYPTR_HPP#define ENTITYPTR_HPP// C++ standard library includes:// Boost includes:#include <boost/shared_ptr.hpp>// 3rd-party includes:// Project includes:typedef boost::shared_ptr<class Entity> EntityPtr;#endif // #ifndef ENTITYPTR_HPP

[Edit: Oops, too late.]
The way that boost::shared_ptr gets around needing the full definition of the contained type is actually kind of neat. Basically you need the full definition of a class when you create it, destroy it or you use any member functions. But instead of destroying the object pointed to by stored pointer directly, the smart pointer calls a user defined function on the pointer, which is set when the smart pointer is created. This avoids the dependency on the full type in the shared_ptr destructor.
The other neat thing this gets you is the ability to define a custom destruction functor instead. This is intensely useful for easily C++ifying other libraries. For instance:

#include <newton.h>class NewtonBodyDeleter{public:    NewtonBodyDeleter(shared_ptr<const NewtonWorld> const& world) : m_world(world) { }    void operator()(NewtonBody * body)    {        NewtonDeleteBody(m_world.get(), body);    }    shared_ptr<const NewtonWorld> m_world;};shared_ptr<NewtonBody> MakeNewtonBody(shared_ptr<const NewtonWorld> const& world, shared_ptr<const NewtonCollision> const& collision){    NewtonBody * body = NewtonCreateBody(world.get(), collision.get());    return shared_ptr(body, NewtonBodyDeleter(world));}

Bingo: the NewtonBody will delete itself at the appropriate time, and will keep the World alive while it exists. Neat, huh?
Quote:Original post by Sneftel
Bingo: the NewtonBody will delete itself at the appropriate time, and will keep the World alive while it exists. Neat, huh?


Actually: Yes!

Lizard

This topic is closed to new replies.

Advertisement