C++ 直接在无序映射的方法中使用哈希,而不是在生成哈希的用户定义对象中使用哈希

C++ 直接在无序映射的方法中使用哈希,而不是在生成哈希的用户定义对象中使用哈希,c++,hash,unordered-map,C++,Hash,Unordered Map,所以我创建了一个类,在无序的_映射中用作散列 class-MyClass { 散列类型mHash=0; hash_type hash(){return mHash;} 布尔运算符!=(常量MyClass&rhs)常量; 布尔运算符==(常量MyClass&rhs)常量; } 名称空间标准 { 模板 结构散列 { hash_type运算符()(const MyClass&k)const noexcept { 返回k.hash(); } }; } 它的工作如预期,但我想添加一些功能。 我希望在使用

所以我创建了一个类,在无序的_映射中用作散列

class-MyClass
{
散列类型mHash=0;
hash_type hash(){return mHash;}
布尔运算符!=(常量MyClass&rhs)常量;
布尔运算符==(常量MyClass&rhs)常量;
}
名称空间标准
{
模板
结构散列
{
hash_type运算符()(const MyClass&k)const noexcept
{
返回k.hash();
}
};
}
它的工作如预期,但我想添加一些功能。 我希望在使用无序映射函数(如find和erase)时能够使用散列本身。 现在我必须这样做:

void_erase_key(const MyClass&key){umap.erase(key);}
但我也希望能够做到这一点:

void\u erase\u key(常量散列类型key){umap.erase(key);}

当使用诸如查找和擦除之类的方法时,是否可以直接使用散列而不是生成散列的对象?

如果我理解正确,您希望有一个
std::unordered_映射
,这样您也可以使用
hash_type
进行查询,并且如果
std::hash{(m),您就有了
hash_type h==MyClass m
If
std::hash}(m)==h
。这是正确的吗

这在C++17中是不可能的。使用C++20,将添加透明哈希的功能。你可以简单地读一下。使用此选项,地图必须满足某些属性

  • 您的相等类型
    Eq
    必须提供成员类型
    Eq::is_transparent
    ,即您必须使用is_transparent=some_类型放置
    在其中。(确切的类型是没有后果的。)
  • 类型为
    Eq
    的对象必须提供一个重载,以比较您想要使用的所有可能的类型组合。即为
    (MyClass,MyClass)
    (MyClass,哈希类型)
    提供重载
  • 您的散列类型
    散列
    必须提供成员类型
    散列::transparent_key_equal
    ,因此再次使用transparent_key_equal=some_type放置
    在其中
  • 类型为
    Hash
    的对象必须可以用您想要使用的每种类型调用。也就是说,对于
    MyClass
    hash\u类型
    ,必须有一个
    操作符()
    重载
对于
Eq
您可以使用
std::equal_to
(请注意空菱形!),如果您为适当的类型提供公共可访问的
操作符==
。这是不是
无序映射的默认值

据我所知,
std::hash
没有analagon,因此您必须为此添加自己的类型,并将其提供给映射

C++20之前,如果要保留密钥类型,唯一可以做的就是编写从
hash\u type
MyClass
的转换

但我感觉到了一个基本问题,即如果
MyClass
的两个对象具有相同的散列,那么它们是相同的。如果这是无意的,您应该真正修复它。如果是有意的,请确保
操作符==(MyClass,MyClass)
也只比较哈希


在后一种情况下,您的问题有一个简单的解决方案。将地图更改为
std::unordered_map
,并对用于查询地图的每个
MyClass
进行散列。如果您需要反向查找从散列中获取
MyClass
,如果可能的话,可以编写一个从
hash\u type
MyClass
的转换函数,否则添加另一个
std::unordered\u map
,在这里存储您曾经使用过的
MyClass
类型的每个对象。

如果我理解正确,您希望有一个
std::unordered_映射
,这样您也可以使用
hash_类型
进行查询,并且您有
hash_类型h==MyClass m
if
std::hash{}(m)==h
。这是正确的吗

这在C++17中是不可能的。使用C++20,将添加透明哈希的功能。你可以简单地读一下。使用此选项,地图必须满足某些属性

  • 您的相等类型
    Eq
    必须提供成员类型
    Eq::is_transparent
    ,即您必须使用is_transparent=some_类型放置
    在其中。(确切的类型是没有后果的。)
  • 类型为
    Eq
    的对象必须提供一个重载,以比较您想要使用的所有可能的类型组合。即为
    (MyClass,MyClass)
    (MyClass,哈希类型)
    提供重载
  • 您的散列类型
    散列
    必须提供成员类型
    散列::transparent_key_equal
    ,因此再次使用transparent_key_equal=some_type放置
    在其中
  • 类型为
    Hash
    的对象必须可以用您想要使用的每种类型调用。也就是说,对于
    MyClass
    hash\u类型
    ,必须有一个
    操作符()
    重载
对于
Eq
您可以使用
std::equal_to
(请注意空菱形!),如果您为适当的类型提供公共可访问的
操作符==
。这是不是
无序映射的默认值

据我所知,
std::hash
没有analagon,因此您必须为此添加自己的类型,并将其提供给映射

C++20之前,如果要保留密钥类型,唯一可以做的就是编写从
hash\u type
MyClass
的转换

但我感觉到了一个基本问题,即如果
MyClass
的两个对象具有相同的散列,那么它们是相同的。如果这是无意的,您应该真正修复它。如果是有意的,请确保
操作符==(MyClass,MyClass)
也只比较哈希

在后一种情况下,您的问题有一个简单的解决方案。将地图更改为