17

I need to do custom deleter for shared_ptr. I know that this can be done in a similar way:

std::shared_ptr<SDL_Surface>(Surf_return_f(), MyDeleter);

But I would like to make them in the style of my custom deleter for unique_ptr:

struct SDL_Surface_Deleter {
    void operator()(SDL_Surface* surface) {
        SDL_FreeSurface(surface);
    }
};

using SDL_Surface_ptr = std::unique_ptr<SDL_Surface, SDL_Surface_Deleter>;

Is there any way to do this?

3
  • What do you mean by "in the style of my custom deleter for unique_ptr"? Commented Mar 6, 2020 at 16:52
  • 3
    To make it look something like this: using SDL_S_ptr = std::shared_ptr<SDL_Surface, SDL_Surface_Deleter>; I would like to be able to use my type, without having to specify MyDeleter every time when creating a variable. Commented Mar 6, 2020 at 16:55
  • 2
    Deleters are different for shared_ptr and unique_ptr. unique_ptr stores the deleter directly in the pointer so different deleters have different pointer types. Usually this is a problem because you can't have different deleters in the same pointer type. shared_ptr stores it on the heap, so it doesn't have that problem. Commented Mar 6, 2020 at 17:02

3 Answers 3

24

It seems that you're trying to define a type alias that means "std::shared_ptr with my deleter type". There's no such thing, because std::shared_ptr has a type-erased deleter (the deleter is not part of the type).

Instead, you could create a custom version of make_shared:

template <class... Args>
std::shared_ptr<SDL_Surface> make_sdl_surface(Args&&... args) {
    return std::shared_ptr<SDL_Surface>(new SDL_Surface(std::forward<Args>(args)...),
                                        SDL_Surface_Deleter{});
}
Sign up to request clarification or add additional context in comments.

Comments

14

Unlike a unique_ptr, the deleter for a shared_ptr is not part of the type. You must pass the deleter to the constructor of the shared_ptr.

You could wrap it in a function instead:

std::shared_ptr<SDL_Surface> make_shared_surface(SDL_Surface* surface)
{
    return std::shared_ptr<SDL_Surface>(surface, MyDeleter);
}

and then call make_shared_surface(Surf_return_f()).

Comments

0
// use lambda expression for deleter for shared pointer
// I used this very code in my SDL wrapper classes except I use textures not surfaces
// note SDL_Surface* raw_surface_ptr is what you get from calling the SDL function
m_surface_ptr = std::shared_ptr< SDL_Surface >(
    raw_surface_ptr,
    [](SDL_Surface* s)
    {
        if (t) SDL_DestroySurface( t );
    }   );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.