您可以使用自定义比较器将std :: map转换为无序映射吗?

时间:2019-05-22 05:45:15

标签: c++ stl containers

由于使用了我不想编辑其代码的库,我发现自己需要使用std::map<Identifier, String>

struct compareIdentifiers
{
    bool operator()(const Identifier& a, const Identifier& b) const
    {
        // return a < b;
        return true;
    }
};

typedef std::map<Identifier, String, compareIdentifiers> IdentifierMap;

我应该返回true还是false?无需进行比较。我想返回true或false会在效率上产生巨大的差异,因为一个会导致地图重新排序,而另一个不会……对吗?

我尝试使用std::unordered_map<Identifier, String>,但出现错误:

错误C2280'std :: hash <_Kty> :: hash(void)':尝试引用已删除的函数

4 个答案:

答案 0 :(得分:7)

始终返回true无效。例如,这意味着A < BB < A都是正确的。这与std::map比较器的要求相矛盾,即它强加了strict weak ordering。完全有可能返回true会使您的程序崩溃。

始终返回false是有效的,这实际上意味着所有键都被视为相等。因此只能向地图添加一个关键点(感谢aschepler进行更正)。

什么阻止了您编写明智的比较器?

答案 1 :(得分:3)

  

我尝试使用std :: unordered_map但出现错误:

     

错误C2280'std :: hash <_Kty> :: hash(void)':尝试引用已删除的函数

这是由于使用std::hash实例的无序映射所致,但是其对Identifier类的专门化已删除了operator()。现在,您有两个选择:

  1. 您的类型的专业知识std::hash

    namespace std
    {
    template<>
    class hash
    {
    public:
    std::size_t operator()(Identifier const&) const
    {
        return /* whatever is appropriate */;
        // best is if you can base the hash code on already defined
        // hashes of its members
    }
    };
    }

  2. 编写您自己的哈希类(再次提供operator())并将其作为第三个模板参数提供给您的无序映射:std::unordered_map<Identifier, String, MyHash>

答案 2 :(得分:0)

通过查看类的实现及其返回类型以及其返回类型的返回类型,我能够为该类创建自定义哈希,直到找到一系列可以返回标准类型的有效方法为止,我可以返回该{ 1}}具有特定于类型的专长。可以在这里找到列表:http://www.cplusplus.com/reference/functional/hash/

std::hash

如果我想使用struct IdentifierHash { size_t operator()(const juce::Identifier& v) const { std::hash<char*> hash; return hash(v.getCharPointer().getAddress()); } }; typedef std::unordered_map<Identifier, String, IdentifierHash> IdentifierMap; ,则可以创建一个类似的比较器:

std::map

答案 3 :(得分:-4)

调用您的二进制运算符的参数lho和tho(左操作数和右操作数),它将立即使您清楚期望返回什么。 (如果是lho https://en.cppreference.com/w/cpp/named_req/Compare

打破一个是如此容易,我只是学到了很难的方法。

m2c