【问题标题】:Can't return nullptr for unique_ptr return type无法为 unique_ptr 返回类型返回 nullptr
【发布时间】:2023-04-03 03:26:01
【问题描述】:

我正在为SDL_Texture* 原始指针编写一个包装器,它返回一个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;
}

但它给出了以下错误:

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

根据我的理解,通过 nullptr 代替 unique_ptr 是可以接受的。我尝试在最后一次返回时传递一个空的 unique_ptr:

return TexturePtr();

但在构建过程中出现类似错误。

请让我知道我在这里做错了什么。

环境: 编译器:Visual C++ 14.1

【问题讨论】:

  • 编译器应该如何确定您要使用的删除器?当删除器是指向函数的指针时,采用 nullptr_tunique_ptr 构造函数会被 SFINAE 淘汰。
  • 最好有专用的删除器,而不是在函数上使用指针。 (这将解决你的问题顺便说一句:))

标签: c++ c++11 unique-ptr nullptr


【解决方案1】:

unique_ptr(nullptr_t) 构造函数要求删除器是默认可构造的并且它不是指针类型。您的删除器不满足第二个条件,因为删除器是指向函数的指针。见[unique.ptr.single.ctor]/1[unique.ptr.single.ctor]/4

此限制是一件好事,因为默认构造删除器会导致 nullptr 和未定义的行为,当您尝试调用删除器时,可能会导致段错误。

您可以将您的退货声明更改为

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

或者,提供满足上述要求的删除器。我写的另一个答案中显示了一个这样的选项here

【讨论】:

  • 很抱歉回复晚了@Praetorian,因为这里停电了。衷心感谢您回答我的问题,提供有关标准链接和更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
相关资源
最近更新 更多