具有自定义键类型的STL无序映射

时间:2014-09-13 21:42:47

标签: c++ c++11 stl unordered-map

我有一些与图形相关的C ++代码,它们使用std::map结构。我不需要严格排序元素,因此我想切换到std::unordered_map结构。

代码的相关部分如下:

typedef unsigned size_type;

struct internal_edge{
 size_type node1_uid;
 size_type node2_uid;
};

std::map<size_type, internal_edge> edges_;

当我切换到std::unordered_map时,编译器会抱怨&#34;类模板的模板参数太少&#39; unordered_map&#39;&#34;。我尝试使用默认的哈希和比较器(编辑:感谢@ rems4e获得更正的版本):

struct size_type_hash {
    std::size_t operator()(const size_type& k) const
    {
        return std::hash<size_type>()(k);
    }
};

struct size_type_equal {
    bool operator()(const size_type& lhs, const size_type& rhs) const
    {
        return lhs == rhs;
    }
};

std::unordered_map<size_type, internal_edge, size_type_hash, size_type_equal> edges_;

这仍会产生相同的错误消息:

./Graph.hpp:384:9: error: too few template arguments for class template 'unordered_map'
   std::unordered_map<size_type, internal_edge, size_type_hash, size_type_equal> edges_;
        ^
/usr/bin/../lib/c++/v1/__hash_table:86:28: note: template is declared here
    class _LIBCPP_TYPE_VIS unordered_map;
                           ^
In file included from viewer.cpp:21:
./Graph.hpp:384:82: warning: private field 'edges_' is not used [-Wunused-private-field]
   std::unordered_map<size_type, internal_edge, size_type_hash, size_type_equal> edges_;

我的Makefile:

...
CXX := $(shell which clang++) -stdlib=libc++ -std=gnu++11
...

clang++的输出:

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix

我有点卡在那里,因为这是我第一次进入C ++世界。关于如何使无序地图构造函数工作的任何想法?

2 个答案:

答案 0 :(得分:2)

标准库标题可以以未指定的方式相互包含,标题也可以包含额外的声明,因此当您忘记包含标题时获得的错误(如果有的话)不一定是您所期望的。 / p>

例如,在这里,您包含的一个标题包含libc ++的<__hash_table>内部标题,其中包含unordered_map转发声明。此前向声明不包含默认模板参数(它不能具有默认参数,因为语言规则阻止您在同一范围内的两个声明中给出模板参数默认参数,因此如果确实如此,那么用户也包含{ {1}} - 必须提供默认参数 - 编译器会抱怨),所以当编译器看到你试图使用<unordered_map>和默认参数时,它会抱怨你的模板参数太少而不是{ {1}}未声明。

如果您实际传递了必需数量的模板参数,编译器可能会抱怨您正在尝试实例化已声明但未定义的模板。

修复很简单:包括unordered_mapunordered_map不需要自定义哈希或比较器 - 只需使用默认值。

答案 1 :(得分:-1)

您的问题可能来自错误的复制粘贴,因为您尝试从size_type变量中获取firstsecond个字段,typedef到{{1} }。

用这些替换你的哈希算子,你的代码将编译:

unsigned int

为了确保,不要忘记在文件中包含标题。