raylib中使用指向哈希表的指针调用DrawTexture报错的问题排查
问题描述
我正在开发一款游戏引擎,启动前会通过加载类把所有纹理、音频和音乐文件加载到一个存储shared_ptr的std::unordered_map里,类型是:
std::unordered_map<std::string, std::shared_ptr<Texture2D>>
我的Entity类里的textureMap类型是:
std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Texture2D>>>
用raylib做渲染,DrawTexture函数接受Texture2D类型参数,不是指针。我试了这段代码调用:
DrawTexture(*textureMap->find("Entity"),100, 100, WHITE);
结果报错:
no suitable user-defined conversion from "std::pair<const std::string, std::shared_ptr<Texture2D>>" to "Texture2D" exists
相关代码如下:
/* loader */ class loaderTemp { std::unordered_map<std::string, std::shared_ptr<Texture2D>> textureMap; loaderTemp() { this->textureMap["Entity"] = std::make_shared<Texture2D>(LoadTexture("resources/KeplerEngineLogo.png")); } }; loaderTemp tempLoader(); /* entity */ class entityTemp { std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Texture2D>>> textureMap; entityTemp(std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Texture2D>>> textureMapArg) { textureMap = textureMapArg; DrawTexture(*textureMap->find("Entity"), 100, 100, WHITE); } }; Entity testentity(std::make_shared<std::unordered_map<std::string, std::shared_ptr<Texture2D>>>(tempLoader.textureMap)); // Constructor
注:raylib部分函数无法复现,我需要在Entity类中正确引用Loader类中的Texture2D对象。
解决方法
1. 错误根源
std::unordered_map::find()返回的是指向std::pair<const std::string, std::shared_ptr<Texture2D>>的迭代器,直接解引用迭代器得到的是整个键值对,而非Texture2D对象,这就是报错的核心原因。
2. 正确调用方式
需要先通过迭代器获取键值对的second成员(即shared_ptr<Texture2D>),再解引用智能指针得到实际的Texture2D对象:
// 先检查迭代器有效性,避免找不到纹理导致崩溃 auto it = textureMap->find("Entity"); if (it != textureMap->end()) { DrawTexture(*(it->second), 100, 100, WHITE); }
it->second:提取键值对中的shared_ptr<Texture2D>*(it->second):解引用智能指针,得到Texture2D实例,完全匹配DrawTexture的参数要求
3. 额外代码问题修复
- loader实例化错误:
loaderTemp tempLoader();是函数声明,不是对象实例化,改成loaderTemp tempLoader; - 纹理资源重复持有问题:创建
testentity时用std::make_shared拷贝整个textureMap会导致资源冗余,建议直接传递原map的智能指针:
// 先给loaderTemp的textureMap添加public访问权限,或者提供getter方法 class loaderTemp { public: std::unordered_map<std::string, std::shared_ptr<Texture2D>> textureMap; loaderTemp() { this->textureMap["Entity"] = std::make_shared<Texture2D>(LoadTexture("resources/KeplerEngineLogo.png")); } }; // 正确实例化loader loaderTemp tempLoader; // 创建Entity时传递原map的智能指针 Entity testentity(std::make_shared<std::unordered_map<std::string, std::shared_ptr<Texture2D>>>(tempLoader.textureMap)); // 更高效的方式:确保loader生命周期长于Entity的前提下,直接用原map地址构造shared_ptr // Entity testentity(std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Texture2D>>>(&tempLoader.textureMap));
4. 可选优化
如果频繁查找纹理,可以封装工具函数简化调用:
Texture2D* GetTexture(const std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<Texture2D>>>& map, const std::string& key) { auto it = map->find(key); return (it != map->end()) ? it->second.get() : nullptr; } // 调用示例 Texture2D* tex = GetTexture(textureMap, "Entity"); if (tex) { DrawTexture(*tex, 100, 100, WHITE); }
内容的提问来源于stack exchange,提问作者Bradley Fernandez
相关产品推荐
相关产品推荐

