Указатель понижающего типа введите уровень для использования с shared_ptr - PullRequest
0 голосов
/ 06 сентября 2018

Я выполняю рефакторинг своего кода SDL2, чтобы использовать некоторые новые функции в C ++ 11 и позволяю некоторому shared_ptr обрабатывать очистку. Тогда я наткнулся на эту проблему. Теперь я пишу это при создании контекста openGL.

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);

Проблема в том, что когда я хочу присвоить контекст переменной, я не могу найти нужную вещь для записи в скобках shared_ptr (void в приведенном выше коде).

typedef struct SDL_Window SDL_Window;
typedef void *SDL_GLContext;

Я бы действительно хотел, чтобы оно было в той же форме, что и shared_ptr<SDL_Window>, но, поскольку SDL_GLContext имеет тип указателя, это невозможно. Вы можете видеть, что я использовал void как тип, но если я хочу, чтобы тип был видимым, как я могу «изменить уровень» типа указателя, чтобы он не был указателем типа? Я знаю, как сделать это для переменных, но как мне это сделать с типами?

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Вы, наверное, ищете

std::remove_pointer<SDL_GLContext>::type

Если SDL_GLContext является псевдонимом для void* (или обычно T* для некоторых T), то приведенная выше конструкция является псевдонимом для void (или, как правило, T).

0 голосов
/ 06 сентября 2018

SDL скрывает фактический тип объекта, возвращенный SDL_GL_CreateContext навсегда. Указатель нацелен на конкретный объект контекста ОС, который вам не доступен.

Прекрасно иметь shared_ptr<void>. Под капотом shared_ptr выполняет стирание типа и сохраняет удалитель [1] .

Однако, поскольку он позволяет конвертировать shared_ptr любого типа в shared_ptr<void>, вы можете быть уверены, что этого не произойдет. Для этого вы можете пометить это так:

#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);
}
...