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
It will work. unique_ptr& operator=(nullptr_t) noexcept ; Effects: reset() .
If a function returns a std::unique_ptr<> , that means the caller takes ownership of the returned object. class Base { ... }; class Derived : public Base { ... }; // Foo takes ownership of |base|, and the caller takes ownership of the returned // object.
nullptr is a keyword that can be used at all places where NULL is expected. Like NULL, nullptr is implicitly convertible and comparable to any pointer type. Unlike NULL, it is not implicitly convertible or comparable to integral types.
std::unique_ptr::unique_ptr default constructor (1), and (2) The object is empty (owns nothing), with value-initialized stored pointer and stored deleter.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With