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
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.