c++ - 没有可用于 std::unique_ptr 的适当默认构造函数std::unordered_map 内部
问题描述
这是我之前帖子的延续:(对不起,问题链)
没有可用于 std::unique_ptr 的适当默认构造函数
我遇到了类似的错误,这次是std::unique_ptr
在一个std::unordered_map
容器中:(对不起,我必须把整个代码)
class cGraphics
{
public:
// Creator functions
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> Create_Window(int xWin, int yWin);
std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> Create_Renderer();
bool Create_TextureMap(std::string texid, std::string texres, int r, int g, int b); // Using helper function Create_Texture()
// ctor & dtor
cGraphics(int xWin, int yWin, std::string texid, std::string texres);
~cGraphics();
// Rendering
void ClearScreen();
bool SetRendererDrawColor(int r, int g, int b, int opaque);
void RenderTexture(std::string texres, int xDes, int yDes);
bool Show();
private:
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> m_Window;
std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> m_Renderer;
std::unordered_map<std::string, std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>> m_TextureMap;
// Private default ctor
cGraphics() : m_Window(nullptr, SDL_DestroyWindow), m_Renderer(nullptr, SDL_DestroyRenderer) {}
// Creator helper
SDL_Texture* CreateTextureRawPtr(std::string texres, int r, int g, int b);
std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)> CreateTexture(std::string texres, int r, int g, int b);
};
cGraphics::cGraphics(int xWin, int yWin, std::string texid, std::string texres) : cGraphics()
{
SDL_Init(SDL_INIT_VIDEO);
m_Window = Create_Window(xWin, yWin);
m_Renderer = Create_Renderer();
if (m_Window == nullptr || m_Renderer == nullptr)
{
throw "SDL_Window or SDL_Renderer not ready!";
}
/*if (m_Window == nullptr || m_Renderer == nullptr || !Create_TextureMap(texid, texres, 255, 255, 255))
{
throw "SDL_Window or SDL_Renderer not ready!";
}*/
}
cGraphics::~cGraphics()
{
IMG_Quit();
SDL_Quit();
}
void cGraphics::ClearScreen()
{
SDL_RenderClear(m_Renderer.get());
}
bool cGraphics::SetRendererDrawColor(int r, int g, int b, int opaque)
{
SDL_SetRenderDrawColor(m_Renderer.get(), r, g, b, opaque); // Should use reset here
return true;
}
void cGraphics::RenderTexture(std::string texres, int xDes, int yDes)
{
SDL_Rect g_SrcRect = { 0, 0, 32, 32 }; // hard-coded for test
SDL_Rect g_DesRect = { xDes, yDes, 32, 32 };
SDL_RenderCopy(m_Renderer.get(), m_TextureMap[texres].get(), &g_SrcRect, &g_DesRect);
}
bool cGraphics::Show()
{
SDL_RenderPresent(m_Renderer.get());
}
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> cGraphics::Create_Window(int xWin, int yWin)
{
return std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)>(SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xWin, yWin, SDL_WINDOW_SHOWN), SDL_DestroyWindow);
}
std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)> cGraphics::Create_Renderer()
{
SDL_Renderer* temprenderer = SDL_CreateRenderer(m_Window.get(), -1, 0);
SDL_SetRenderDrawColor(temprenderer, 255, 255, 255, 0xff);
return std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)>(temprenderer, SDL_DestroyRenderer);
}
bool cGraphics::Create_TextureMap(std::string texid, std::string texres, int r, int g, int b)
{
m_TextureMap.emplace(texid, CreateTexture(texres, r, g, b));
return true;
}
SDL_Texture* cGraphics::CreateTextureRawPtr(std::string texres, int r, int g, int b)
{
SDL_Surface* temp = IMG_Load(texres.c_str());
//Set color key
SDL_SetColorKey(temp, SDL_TRUE,
SDL_MapRGB(temp->format, r, g, b));
SDL_Texture* pTexture = SDL_CreateTextureFromSurface(m_Renderer.get(), temp);
SDL_FreeSurface(temp);
return pTexture;
}
std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)> cGraphics::CreateTexture(std::string texres, int r, int g, int b)
{
return std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>(CreateTextureRawPtr(texres, r, g, b), SDL_DestroyTexture);
}
错误信息是:
error C2512: 'std::unique_ptr<SDL_Texture,void (__cdecl *)(SDL_Texture *)>::unique_ptr': no appropriate default constructor available
这与上一个问题绝对相似,但有一个例外:唯一指针位于容器内部。我在想也许我可以把它std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>
放在一个包装类中,并为编译器提供一个包装类的默认 ctor。但这肯定很麻烦,不知道有没有更好的办法。
另一件事是我使用了很多.get()
,我现在明白这是错误的,因为它只返回唯一指针内的原始指针的副本。也许我应该使用.reset()
.
解决方案
推荐阅读
- android - 如何振动安卓手机,直到我点击停止按钮?
- shortest-path - 访问无向加权图所有节点的最短距离
- algorithm - 2 ^ O(log log n) = O(log n) 吗?
- ruby-on-rails - nil 的未定义方法“src”:NilClass Rails LinkThumbnailer
- c++ - 标识符“V”未定义
- c - 在 Raspberry Pi 上读取 PPM 信号
- r - R中的plot():ylim范围与图上的y轴范围不匹配
- database - 如何使用 mongoose 根据 mongodb 中的 3 个键获取记录数?
- docker - 如何构建支持多种语言(c、c++、rust、java、go、python、javascript、nodejs 等)的轻量级 docker 镜像
- javascript - 无法读取未定义的属性“材料”。使用嵌套对象反应 useState