【问题标题】:C2338: The C++ Standard doesn't provide a hash for this type with string and unique_ptrC2338:C++ 标准没有为这种类型提供带有字符串和 unique_ptr 的散列
【发布时间】:2014-03-11 21:55:03
【问题描述】:

我正在尝试实现一个 std::unordered_map,其中 std::string 作为键,std::unique_ptr 作为值。但是,当我尝试编译时,我得到了错误:

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

环顾不同的问题,我知道 C++11 确实包含一个 std::hash ,我看不出为什么会抛出这个错误。我尝试实现自己的哈希函数,就像看到的 here 一样,但它仍然抛出相同的错误。我还尝试使用__declspec(dllexport) 并将包含类的复制构造函数和赋值运算符设为私有,因为在某些线程中建议使 unique_ptr 工作,但无济于事。

这是违规类的代码:

#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

我找不到任何不应该工作的原因,并且我已经尝试了几乎所有我在搜索问题时可以找到的其他解决方案。

我正在使用 MSVC 2012。

非常感谢任何帮助。谢谢。

编辑:添加 AtlasTexture 类:headerimplementation

编辑:我的移动和移动分配的实现:here

【问题讨论】:

  • 您的_registeredIcons 密钥不应该是const - 只是普通的旧std::stringhash 专门用于string 而不是const string)。此外,std::hash(const char*) 将散列指针的地址,而不是指向的文本......这真的是你想要的吗?
  • 好吧,问题在于字符串前面没有 const,我开始收到一个新错误:“ error C2248: 'std::unique_ptr<_ty>::unique_ptr' : cannot access private member在类 'std::unique_ptr<_ty>' " 中声明
  • 我认为这是因为 unique_ptr&lt;&gt; 不是映射到的有效类型...根据 23.2.5.10 “key_type 和 mapped_type 有时需要为 CopyAssignable” - unique_ptr 不是 CopyAssignable。你可以使用shared_ptr
  • @Praetorian:当然......我认为只有当你使用初始化列表时......这就是为什么我要求查看引发错误的代码行。 GCC 曾经有一个 unique_ptr 的错误,有趣的是 Casey 也怀疑 MSVC。

标签: c++ visual-c++ c++11 hash unordered-map


【解决方案1】:

您是否尝试过在 AtlasTexture 中实现所有编译生成的方法?

【讨论】:

  • 老兄,别再让 cmets 冒充答案了。这不太可能与AtlasTexture 有关。他在上面的 cmets 中发布的那个错误很可能意味着他试图在某处复制构造/复制分配 unique_ptr
  • 我为之前的评论道歉。 You may have hit头上的钉子;问题很可能是 OP 没有为AtlasTexture 实现移动构造函数,并且 MSVC 不会隐式生成移动构造函数。
  • 我添加了一个链接,指向我的移动和移动分配的实现。我不熟悉这些,所以我基本上只是实现了我认为标准复制构造函数所做的事情。
【解决方案2】:

我的问题是我如何将std::unique_ptrs 放入地图中。放置它的最佳方法是使用map::emplace() 而不是map::insert()。这是因为std::unique_ptr 没有复制构造函数,并且 emplace 移动对象而不是复制它。感谢@Casey 的回答。

我的另一个问题是使用新的auto 类型从地图中获取配对。同样,因为unique_ptr 无法复制,当auto 更改为std::pair 时会发生这种情况,这会引发编译器错误。一个很好的简单解决方法是使用auto&amp; 而不是auto。感谢@MatthieuM。为此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2018-06-14
    • 2013-06-13
    相关资源
    最近更新 更多