Search code examples
c++c++11unique-ptrnullptr

Can't return nullptr for unique_ptr return type


I am writing a wrapper for SDL_Texture* raw pointer which returns a unique_ptr.

using TexturePtr = std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>;

TexturePtr loadTexture(SDL_Renderer* renderer, const std::string &path) {
    ImagePtr surface =
        loadImage(path);
    if (surface) {
        return TexturePtr(
            SDL_CreateTextureFromSurface(renderer, surface.get())
            , SDL_DestroyTexture);
    }
    return nullptr;
}

But it gives following error:

no suitable constructor exists to convert from "std::nullptr_t" to "std::unique_ptr<SDL_Texture, void (__cdecl *)(SDL_Texture *texture)>"

As per my understanding it's acceptable to pass a nullptr in lieu of unique_ptr. I event tried passing an empty unique_ptr on the last return:

return TexturePtr();

but get similar error during build.

Please let me know what I am doing wrong here.

Env: compiler: Visual C++ 14.1


Solution

  • The unique_ptr(nullptr_t) constructor requires that the deleter be default constructible and that it not be a pointer type. Your deleter does not satisfy the second condition because the deleter is a pointer to function. See [unique.ptr.single.ctor]/1 and [unique.ptr.single.ctor]/4.

    This restriction is a good thing because default constructing your deleter results in a nullptr and undefined behavior, likely resulting in a segfault, when you try to invoke the deleter.

    You can change your return statement to

    return TexturePtr{nullptr, SDL_DestroyTexture};  // or just {nullptr, SDL_DestroyTexture}
    

    Alternatively, provide a deleter that satisfies the above requirements. One such option is shown in another answer I wrote here.