c++ - Knowing when to delete associated user data from a std::map<void *, ...> -


i have map of addresses allows me store arbitrary data objects. basically, library i'm writing has templated function winds storing arbitrary data objects.

std::map<void *, myuserdata> 

this works, until object passed in destroyed, leaving user data in map. want associated user data removed well, need somehow listen destructor of passed in object,

some example code illustrates problem:

#include <map> #include <memory>   struct myuserdata {         int somenum; };  std::map<void *, myuserdata> mymap;  template <typename t> registerobject<t>(const std::shared_ptr<t> & _object) {         static inc = 0;          mymap[(void *)&_object->get()].somenum = inc++; }  struct myobject {         int asdf; };  int main(int _argc, char ** _argv) {         auto obj = std::make_shared<myobject>();         obj->asdf = 5;          registerobject(obj);          obj = 0;          //the user data still there.  want removed @ point. } 

my current solution set custom deleter on shared_ptr. signals me when object's destructor called, , tells me when remove associated user data. unfortunately, requires library create shared_ptr, there no "set_deleter" function. must initialized in constructor.

mylib::make_shared<t>(); //annoying! 

i have user manually remove objects:

mylib::unregister<t>(); //equally annoying! 

my goal able lazily add objects without prior-registration.

in grand summary, want detect when object deleted, , know when remove counterpart std::map.

any suggestions?

p.s. should worry leaving user data in map? chances object allocated same address deleted object? (it end receiving same user data far lib concerned.)

edit: don't think expressed problem initially. rewritten.

from code example, looks external interface is

template <typename t> registerobject<t>(const std::shared_ptr<t> & _object); 

i assume there get-style api somewhere. let's call getregistereddata. (it internal.)

within confines of question, i'd use std::weak_ptr<void> instead of void*, std::weak_ptr<t> can tell when there no more "strong references" object around, won't prevent object being deleted maintaining reference.

std::map<std::weak_ptr<void>, myuserdata> mymap;  template <typename t> registerobject<t>(const std::shared_ptr<t> & _object) {     static inc = 0;      internal_removedeadobjects();      mymap[std::weak_ptr<void>(_object)].somenum = inc++; }  template <typename t> myuserdata getregistereddata(const std::shared_ptr<t> & _object) {     internal_removedeadobjects();     return mymap[std::weak_ptr<void>(_object)]; }  void internal_removedeadobjects() {     auto iter = mymap.cbegin();     while (iter != mymap.cend())     {         auto& weakptr = (*iter).first;          const bool needsremoval = !(weakptr.expired());          if (needsremoval)         {             auto itemtoremove = iter;             ++iter;             mymap.erase(itemtoremove);         }         else         {             ++iter;         }     } } 

basically, std::weak_ptr , std::shared_ptr collaborate , std::weak_ptr can detect when there no more std::shared_ptr references object in question. once case, can remove ancillary data mymap. i'm using 2 interfaces mymap, registerobject , getregistereddata convenient places call internal_removedeadobjects perform clean up.

yes, walks entirety of mymap every time new object registered or registered data requested. modify see fit or try different design.

you ask "should worry leaving user data in map? chances object allocated same address deleted object?" in experience, decidedly non-zero, don't this. :-)


Comments

Popular posts from this blog

python - How to create a legend for 3D bar in matplotlib? -

java - Multi-Label Document Classification -

php - Dynamic url re-writing using htaccess -