0

I am trying to pass a pointer to a function that then sets a unique_ptr inside a struct to the pointer passed in. However, I get the following compile error on the last line of the function.

error C2280: 'std::unique_ptr< ALLEGRO_BITMAP,std::default_delete< ALLEGRO_BITMAP>>::unique_ptr(const std::unique_ptr< ALLEGRO_BITMAP,std::default_delete< ALLEGRO_BITMAP>> &)' : attempting to reference a deleted function

c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr< ALLEGRO_BITMAP,std::default_delete< ALLEGRO_BITMAP>>::unique_ptr'

This diagnostic occurred in the compiler generated function 'Skin::Skin(const Skin &)'

Judging from the errors I believe it has something to do with me adding the delete template for ALLEGRO_BITMAP to namespace std, but I don't know why or how to fix it.

using namespace std;

namespace std {
template<>
class default_delete < ALLEGRO_BITMAP > {
public:
    void operator()(ALLEGRO_BITMAP* ptr) {
        al_destroy_bitmap(ptr);
    }
};
}

typedef struct {
    unique_ptr<ALLEGRO_BITMAP> img;
} Skin;

typedef struct {
    Skin skins[MAX_ENTITY_COUNT];
} World;

unsigned int createBlock(World world, ALLEGRO_BITMAP* img) {
    unsigned int entity = newEntityIndex(world);
    world.skins[entity].img = make_unique<ALLEGRO_BITMAP>(img);
    return entity;
} // error on this line

Any help is appreciated. Thanks.

Community
  • 1
  • 1
janovak
  • 1,247
  • 2
  • 11
  • 18
  • 1) The example given is not self-contained. 2) unique_ptr has certain requirements (see http://stackoverflow.com/a/6089065/2549876). – Hector May 30 '15 at 17:05
  • 1
    You should not be using `make_unique` here. ALLEGRO_BITMAP should only be used through an [opaque pointer](http://en.wikipedia.org/wiki/Opaque_pointer). You should not directly create ALLEGRO_BITMAP objects, which is what `make_unique` will do. You should just use the `unique_ptr` constructor. – Benjamin Lindley May 30 '15 at 17:13

1 Answers1

3

In your createBlock function you take World by value which means that it will be copied. However, you can't copy a unique_ptr so that is where your error comes from. This would also mean that setting the unqiue_ptr in the function wouldn't have any effect.

Instead you should take World by reference:

unsigned int createBlock(World& world, ALLEGRO_BITMAP* img) {
    unsigned int entity = newEntityIndex(world);
    world.skins[entity].img = make_unique<ALLEGRO_BITMAP>(img);
    return entity;
}

Note that the same is true for the call to newEntityIndex and that the arguments to make_unique will be passed to the ALLEGRO_BITMAP constructor.

So what you probably want is:

world.skins[entity].img.reset(img);
Stephan Dollberg
  • 27,667
  • 11
  • 72
  • 104