C++ std::map 缓存,使用 std::string 作为键值

C++ std::map cache using std::string as the key value

本文关键字:std 键值 string map 缓存 C++ 使用      更新时间:2023-10-16

我正在为学校的游戏编写缓存。这个想法是,这个缓存存储网格、材质等,并使用驱动器上的位置作为键,因此它们只需要加载一次,然后可以通过插入它们的相同命令从缓存中检索。我遇到的问题似乎是我无法将项目添加到除构造函数之外的任何地方的缓存中。相关代码如下:

#include <map>
#include "mge/materials/AbstractMaterial.hpp"
#include <string>
class Resources
{
public:
~Resources();
static Resources* GetInstance();
AbstractMaterial* GetMaterial(std::string location) const;
Mesh* GetMesh(std::string location) const;
private:
Resources();
static Resources* _instance;
std::map<std::string, AbstractMaterial*>    _materialCache;
std::map<std::string, Mesh*>                _meshCache;
};

加载网格的相关方法(材质几乎相同):

Mesh* Resources::GetMesh(std::string location) const
{
Mesh* foundMesh = _meshCache.find(location)->second;
if (foundMesh == nullptr)
{
std::cout << "The requested mesh was not stored in the cache yet!" << std::endl;
foundMesh = Mesh::load(config::MGE_MODEL_PATH + location);
if (foundMesh == nullptr)
{
std::cout << "The requested mesh was not found on the disk either!" << std::endl;
return nullptr;
}
else
{
//_meshCache[location] = foundMesh; //not working
//_meshCache.insert(std::pair<std::string, Mesh* >(location, foundMesh)); //
}
}
else
{
std::cout << "The requested mesh was found in the cache!" << std::endl;
}
return foundMesh;
}

插入到地图中的两个版本似乎都不起作用,它们甚至在编译之前都给出了相当奇怪的错误:

第一个变体(map[key] = value)给出以下错误:

"no operator "[]" matches these operands"

"binary '[': no operator found which takes a left-hand operand of type 'const std::map<std::string,AbstractMaterial *,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' (or there is no acceptable conversion)"

第二个变体(map.insert(Key, Value))给出了这些错误:

"no instance of overloaded function "std::map<_Kty, _Ty, _Pr, _Alloc>::insert [with _Kty=std::string, _Ty=Mesh *, _Pr=std::less<std::string>, _Alloc=std::allocator<std::pair<const std::string, Mesh *>>]" matches the argument list and object (the object has type qualifiers that prevent a match)"

"'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::insert': 6 overloads have no legal conversion for 'this' pointer"

我不理解这些错误中的任何一个,因为在我看来它们相当模糊,我从中得到的也不能解释为什么这段代码在构造函数中有效,但在 GetMaterial 和 GetMesh 方法中不起作用。

我想使用这个系统轻松/快速地加载屁股,因此将不胜感激。

问题是你已经声明了GetMesh(std::string location) const

不能修改const成员函数中的成员变量。

但是,您实质上是在实现延迟加载模式。从用户的角度来看,他们的对象没有改变,所以你确实想修改你的缓存!(这在逻辑上是const,但不是物理上的)

将它们声明为mutable

mutable std::map<std::string, AbstractMaterial*>    _materialCache;
mutable std::map<std::string, Mesh*>                _meshCache;

编辑: 如果要在多线程上下文中访问类,则应同步mutable变量,就像同步任何非 const 变量一样。查看其他关于它的 StackOverflow 讨论

您不能在const std::map上使用operator[],因为它可能会尝试插入新元素。出于显而易见的原因,您也不能insert进入const std::map。你的方法是常量,所以_meshCachethis的成员,被const对待。也许您想使_meshCache可变?请注意,使用mutable会对并发性产生影响。