在 std::unordered_map 中使用模板键

Posted

技术标签:

【中文标题】在 std::unordered_map 中使用模板键【英文标题】:using a templated key in std::unordered_map 【发布时间】:2016-05-01 12:53:16 【问题描述】:

我不明白为什么我的编译器不接受下面的代码

#include <unordered_set>
#include <unordered_map>

template<class T>
using M = std::unordered_set<T>;

template<class T>
using D = M<T>;

template<class T>
using DM = std::unordered_map < typename M<T>::const_iterator    // Problem
                              , typename D<T>::const_iterator >; // Problem

int main(int argc, char ** argv)

    D<int> d;
    M<int> m;
    DM<int> dm; // Problem

编译命令是

clang++ -std=c++14 test.cpp -o test

编译器错误消息摘录是

/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/hashtable_policy.h:85:11: error: 
      implicit instantiation of undefined template
      'std::hash<std::__detail::_Node_const_iterator<int, true, false> >'
        noexcept(declval<const _Hash&>()(declval<const _Key&>()))>

为什么不允许在std::unordered_map 中使用typename M&lt;T&gt;::const_iterator 作为键?

【问题讨论】:

另外,我不认为那些typenames 是必需的,因为MD 都不是模板参数。 【参考方案1】:

因为std::unordered_map的哈希默认模板参数是std::hash,它没有提供迭代器的实现。

你需要为其提供用户定义的哈希,比如

struct iterator_hash 
    template <typename I>
    std::size_t operator()(const I &i) const 
        return std::hash<int>()(*i); // or return sth based on i
    
;

【讨论】:

以上是关于在 std::unordered_map 中使用模板键的主要内容,如果未能解决你的问题,请参考以下文章

C++ std::unordered_map 中使用的默认哈希函数是啥?

向 std::unordered_map 插入数据时访问冲突

如何在 std::tuple 中合并 std::unordered_map?

在 std::map 和 std::unordered_map 之间进行选择 [重复]

在 C++ std::unordered_map 中预分配桶

C++17 中 std::unordered_map 的推导指南