I am trying to implement an std::unordered_map with std::string as the key and std::unique_ptr as the value. However, when I try to compile, I get the error:

error C2338: The C++ Standard doesn't provide a hash for this type.

Looking around at different questions, I know that C++11 does indeed include a std::hash < std::string >, and I can see no reason why this error would be thrown. I've tried to implement my own hashing function, like the one seen here, but it is still throwing the same error. I have also tried using __declspec(dllexport) and making the copy constructor and assignment operator for the containing class private, as it is suggested in some threads to make unique_ptr work, but to no avail.

Here is the code for the offending class:

#ifndef __TEXTURE_MAP_H__
#define __TEXTURE_MAP_H__

#include <unordered_map>
#include <vector>
#include <memory>
#include <string>

//__declspec for std::unique_ptr compat.
class /*__declspec(dllexport)*/ TextureMap : virtual public IconRegister
{
private:
    uint32 _textureId;
    std::unordered_map<const std::string, std::unique_ptr<AtlasTexture> > _registeredIcons;
    std::unordered_map<const char*, AtlasTexture*> _uploadedIcons;
    std::vector<AtlasTexture*> _animatedIcons;

public:
    TextureMap();
    ~TextureMap();

    uint32 getTextureId();

    void loadTextureAtlas();

    /* override */ IIcon& registerIcon(const char*);
    void registerIcons();

private:
    TextureMap(const TextureMap& other) { }
    TextureMap& operator= (const TextureMap& other) { return *this; };
};

#endif

I cannot find any reason this should not be working, and I've tried pretty much every other solution I could find when I searched for the problem.

I am using MSVC 2012.

Any help is greatly appreciated. Thanks.

EDIT: Addition of the AtlasTexture class: header and implementation

EDIT: My implementation of the move and move assignment: here.

有帮助吗?

解决方案 2

My issue was with how I was placing the std::unique_ptrs into the map. The best way to place it in is to use map::emplace() instead of map::insert(). This is becasue there is no copy constructor for std::unique_ptr and emplace moves the object instead of copies it. Thanks to @Casey for this answer.

My other issue was using the new auto type in order to get the pairs from the map. Again, becasue the unique_ptr cannot be copied, which happens when auto gets changed to std::pair, this was throwing a compiler error. The nice easy fix for this was to use auto& instead of auto. Thanks to @MatthieuM. for this.

其他提示

Have you tried to implement all compile generated methods af AtlasTexture?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top