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

时间:2017-03-13 18:39:18

标签: c++ dictionary caching

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

#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方法中没有用。

我想使用这个系统进行简单/快速的assset加载,所以非常感谢帮助。

2 个答案:

答案 0 :(得分:2)

您无法在operator[]上使用const std::map,因为它可能会尝试插入新元素。出于显而易见的原因,您也无法insert加入const std::map。您的方法是常量,因此_meshCache的成员this被视为const。也许你想制作_meshCache mutable?请注意,使用mutable会影响并发性。

答案 1 :(得分:2)

问题是您已声明GetMesh(std::string location) const

您无法修改const成员函数中的成员变量。

但是,您实际上是在实现延迟加载模式。从用户的角度来看,他们的对象没有改变,所以你真的想要修改你的缓存! (It's logically const, but not physically so

将其声明为mutable

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

编辑: 如果您在多线程上下文中访问类,则应该同步mutable变量,就像同步任何非const变量一样。 Check out this other StackOverflow discussion about it