1

Im refactoring my SDL2 code to make use of some of the new functionalities with C++11 and letting some shared_ptr handling the cleanup. Then I stumbled upon this problem. Now i write this, when creating a openGL context.

auto window = shared_ptr<SDL_Window>(SDL_CreateWindow(
        "Opengl stuff", 0, 0, width, height, windowFlags),
        SDL_DestroyWindow);


auto context = shared_ptr<void>(
        SDL_GL_CreateContext(window.get()),
        SDL_GL_DeleteContext);

The problem is when I want to assign to the variable context, i cannot find the right thing to write in the brackets of shared_ptr (void in the code above).

typedef struct SDL_Window SDL_Window;
typedef void *SDL_GLContext;

I would really want it in the same form as shared_ptr<SDL_Window>, but since SDL_GLContext is of a pointer type it is not possible. You can see that what I've done is using void as a type, but if I want the type to be visible, how can I "change the level" of the pointer type to be of non pointer type? I know how to do it for variables, but how do I do it with types?

Nikita Kniazev
  • 3,728
  • 2
  • 16
  • 30
Lasersköld
  • 2,028
  • 14
  • 20
  • 1
    `std::remove_pointer::type` – Igor Tandetnik Sep 06 '18 at 14:16
  • Hmm.. That may actually be a solution to the problem. If there was a shorter to write it way I would like to use it, but if you write that as an answer I would accept it. – Lasersköld Sep 06 '18 at 14:39
  • Typedef it once, then use the typedef name. – Igor Tandetnik Sep 06 '18 at 14:55
  • Absolutely. That was what I was looking for, could you write that as a answer so I can accept it? Maybe I would not use it now because the code already is longer less readable then when I started, but I was looking for the concept of remove_pointer and I am perfectly happy with that. – Lasersköld Sep 06 '18 at 16:14

2 Answers2

2

You are probably looking for

std::remove_pointer<SDL_GLContext>::type

If SDL_GLContext is an alias for void* (or generally T* for some T), then the construct above is an alias for void (or generally T).

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
1

SDL hides the actual type of object returned by SDL_GL_CreateContext for good. The pointer targets OS specific context object which is not exposed to you.

It is perfectly fine to have shared_ptr<void>. Under the hood shared_ptr performs type erasure and stores the deleter [1].

However, because it allows to convert shared_ptr of any type to shared_ptr<void> you may want to be sure it will not happen. To achieve this you can tag it like this:

#include <memory>
#include <iostream>

struct sdl_context_tag;

typedef void* SDL_GLContext;
void bar(SDL_GLContext)
{
}

void foo(std::shared_ptr<sdl_context_tag> context)
{
    bar(context.get());
}

int main()
{
    auto ptr = std::static_pointer_cast<sdl_context_tag>(std::shared_ptr<void>(new int, [](int * p){ delete p; std::cout << "int deleted\n"; }));
    foo(ptr);
}
Nikita Kniazev
  • 3,728
  • 2
  • 16
  • 30
  • It is usable stuff that you're writing but I already knew about it and it is not what i was after. I was after remove_pointer that Igor wrote about. – Lasersköld Sep 06 '18 at 16:17