4

I have a SpriteManager class that loads and caches sprites for me, and removes unused sprites from the cache. That's the idea anyways, I'm a bit stuck. I have a map<string,weak_ptr<ALLEGRO_BITMAP>> where I'm storing the sprites, and use the weak_ptr to spawn off shared_ptr's. Now I'm trying to use a deleter that also removes the bitmap from the map, it looks like this (not working, obviously):

[&bitmaps](ALLEGRO_BITMAP* bmp){
        for(auto it = bitmaps.begin(); it!=bitmaps.end(); ++it) {
            if((*it).second == bmp) {
                bitmaps.erase(it);
                al_destroy_bitmap(bmp);
                break;
            }
        }
}

bitmaps being the map I was talking about. Of course I can't compare (*it).second and bmp, but I also can't lock the weak_ptr because I'm in the deleter. Do I really have no other choice other than to keep both the weak and the raw pointer around?

Cubic
  • 14,902
  • 5
  • 47
  • 92
  • There shouldn't be any need to delete the raw pointer yourself. The shared_ptrs that use it will take care of the delete when the reference count goes to zero. Of course if you need a special deleter, that should be supplied during share_ptr construction. – Anon Mail Jul 31 '12 at 12:29
  • I need to remove the bitmap from my map when the bitmap is deleted, I thought I expressed that quite clearly. And I AM supplying a special deleter, the problem is with it's definition. – Cubic Jul 31 '12 at 12:31

1 Answers1

5

Store iterator to the weak_ptr in the map in the deleter along with &bitmaps. then remove with it.

[&bitmaps, iter](ALLEGRO_BITMAP* bmp){
    bitmaps.erase(iter);
    al_destroy_bitmap(bmp);
}
yuri kilochek
  • 12,709
  • 2
  • 32
  • 59
  • Wait, does the iterator actually stay valid if the map is modified in the meantime. – Cubic Jul 31 '12 at 12:35
  • @Cubic yes, for `std::map` this is guaranteed. – yuri kilochek Jul 31 '12 at 12:37
  • @Cubic, yuri kilocheck: It doesn't stay valid if the element pointed to by the iterator is removed, so the answer is no. Look [here](http://stackoverflow.com/a/6438087/201270) for the invalidation rules (in c++03, but I doubt that changed for c++11) – Grizzly Jul 31 '12 at 15:30
  • @Grizzly obviously if you delete the element referred to by the iterator then iterator is invalidated. I assumed by modification you meant inserting/erasing other elements. But why do you care about that? Can this weak_ptr be erased from map from another place? – yuri kilochek Jul 31 '12 at 15:36
  • No, it can't. And of course the iterator is invalid if the element is erased, I wasn't referring to that either. Your answer worked like a charm for me. I assume Grizzly just wanted to make the point that what you said wasn't _technically_ correct because there are modifying operations that invalidate iterators or something. – Cubic Aug 01 '12 at 12:54