向下指针键入一个级别以用于 shared_ptr

Step down pointer type a level for use with shared_ptr

我正在重构我的 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的括号里(上面代码中是空的)。

typedef struct SDL_Window SDL_Window;
typedef void *SDL_GLContext;

我真的希望它与 shared_ptr<SDL_Window> 具有相同的形式,但由于 SDL_GLContext 是指针类型,因此不可能。你可以看到我做的是用void作为类型,但是如果我想让类型可见,我怎么让指针类型的"change the level"变成非指针类型呢?我知道如何为变量做,但如何为类型做?

SDL 永久隐藏了 SDL_GL_CreateContext 返回的对象的实际类型。指针指向未向您公开的 OS 特定上下文对象。

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

您可能正在寻找

std::remove_pointer<SDL_GLContext>::type

如果 SDL_GLContextvoid* 的别名(或者通常 T* 对于某些 T),那么上面的构造是 void 的别名(或通常 T)。