智能指针(unique_ptr) 自定义删除器错误 C2027 & C2338

Smart pointer(unique_ptr) custom deleter error C2027 & C2338

我尝试在 SDL2 中使用智能指针,我需要一个自定义删除器。我使用此代码并得到错误 C2027(使用未定义的类型 SDL_Texture)和 C2338(无法删除不完整的类型)

ftexture = std::make_unique<SDL_Texture>(TTF_RenderText_Solid(font, fontData.c_str(), fontColor),
        [=](SDL_Texture* texture) {SDL_DestroyTexture(texture); });

我的 class 中的这个变量看起来像这样:

std::unique_ptr <SDL_Texture> ftexture = nullptr;

首先,TTF_RenderText_Solid() returns 一个 SDL_Surface*,而不是 SDL_Texture*SDL_Surface 并非源自 SDL_Texture

其次,您不能使用 std::make_unique() 指定自定义删除器。第一个模板参数用作结果 std::unique_ptrT 类型,其余模板参数用作输入参数,它们都传递给 T 的构造函数。在您的示例中,TSDL_Texture,并且没有 SDL_Texture 的构造函数将 SDL_Surface* 和 lambda 作为输入。

要使用自定义删除器,您需要将删除器的类型指定为 std::unique_ptr 的模板参数,std::make_unique() 不允许您这样做,因此您必须使用 std::unique_ptr直接。

删除器应该是一个单独的类型而不是 lambda:

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

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

...

fsurface = SDL_Surface_ptr(
    TTF_RenderText_Solid(font, fontData.c_str(), fontColor)
);

但是如果你真的想使用 lambda,你可以这样做:

using SDL_Surface_Deleter = void (*)(SDL_Surface*);
using SDL_Surface_ptr = std::unique_ptr<SDL_Surface, SDL_Surface_Deleter>;
SDL_Surface_ptr fsurface;

...

fsurface = SDL_Surface_ptr(
    TTF_RenderText_Solid(font, fontData.c_str(), fontColor),
    [](SDL_Surface* surface) { SDL_FreeSurface(surface); }
);

或者,您可以直接使用 SDL_FreeSurface() 作为实际的删除器:

using SDL_Surface_ptr = std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>;
SDL_Surface_ptr fsurface;

...

fsurface = SDL_Surface_ptr(
    TTF_RenderText_Solid(font, fontData.c_str(), fontColor),
    &SDL_FreeSurface
);