unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,

存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历。

所以使用时map的key需要定义operator<。而unordered_map需要定义hash_value函数并且重载operator==。但是很多系统内置的数据类型都自带这些,

那么如果是自定义类型,那么就需要自己重载operator<或者hash_value()了。

结论:如果需要内部元素自动排序,使用map,不需要排序使用unordered_map

map使用案例:

  1. #include<string>
  2. #include<iostream>
  3. #include<map>
  4.  
  5. using namespace std;
  6.  
  7. struct person
  8. {
  9. string name;
  10. int age;
  11.  
  12. person(string name, int age)
  13. {
  14. this->name = name;
  15. this->age = age;
  16. }
  17.  
  18. bool operator < (const person& p) const
  19. {
  20. return this->age < p.age;
  21. }
  22. };
  23.  
  24. map<person,int> m;
  25. int main()
  26. {
  27. person p1("Tom1",);
  28. person p2("Tom2",);
  29. person p3("Tom3",);
  30. person p4("Tom4",);
  31. person p5("Tom5",);
  32. m.insert(make_pair(p3, ));
  33. m.insert(make_pair(p4, ));
  34. m.insert(make_pair(p5, ));
  35. m.insert(make_pair(p1, ));
  36. m.insert(make_pair(p2, ));
  37.  
  38. for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
  39. {
  40. cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
  41. }
  42.  
  43. return ;
  44. }

输出为:(根据age进行了排序的结果)

Tom1    20
Tom3    22
Tom4    23
Tom5    24
因为Tom2和Tom3的age相同,由我们定义的operator<只是比较的age,所以Tom3覆盖了Tom2,结果中没有Tom2。

如果运算符<的重载是如下

  1. bool operator < (const person &p)const{
  2. return this->name < p.name;
  3. }

输出结果: 按照 那么进行的排序,如果有那么相同则原来的那么会被覆盖

Tom1    20

Tom2    22

Tom3    22

Tom4    23

Tom5    24

unordered_map使用案例:

  1. #include<string>
  2. #include<iostream>
  3. #include<unordered_map>
  4. using namespace std;
  5.  
  6. struct person
  7. {
  8. string name;
  9. int age;
  10.  
  11. person(string name, int age)
  12. {
  13. this->name = name;
  14. this->age = age;
  15. }
  16.  
  17. bool operator== (const person& p) const
  18. {
  19. return name==p.name && age==p.age;
  20. }
  21. };
  22.  
  23. size_t hash_value(const person& p)
  24. {
  25. size_t seed = ;
  26. std::hash_combine(seed, std::hash_value(p.name));
  27. std::hash_combine(seed, std::hash_value(p.age));
  28. return seed;
  29. }
  30.  
  31. int main()
  32. {
  33. typedef std::unordered_map<person,int> umap;
  34. umap m;
  35. person p1("Tom1",);
  36. person p2("Tom2",);
  37. person p3("Tom3",);
  38. person p4("Tom4",);
  39. person p5("Tom5",);
  40. m.insert(umap::value_type(p3, ));
  41. m.insert(umap::value_type(p4, ));
  42. m.insert(umap::value_type(p5, ));
  43. m.insert(umap::value_type(p1, ));
  44. m.insert(umap::value_type(p2, ));
  45.  
  46. for(umap::iterator iter = m.begin(); iter != m.end(); iter++)
  47. {
  48. cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
  49. }
  50.  
  51. return ;
  52. }

对于hash_value的重载没有成功,在vs2013上报错。

C++11 新特性: unordered_map 与 map 的对比的更多相关文章

  1. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  2. 在C++98基础上学习C++11新特性

    自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...

  3. C++11新特性总结 (一)

    1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...

  4. C++11新特性——大括号初始化

    C++11之前,C++主要有以下几种初始化方式: //小括号初始化 string str("hello"); //等号初始化 string str="hello" ...

  5. C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)

    因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...

  6. C++11新特性总结 (二)

    1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...

  7. C++ 11 新特性

    C++11新特性:          1.auto          2.nullptr          3.for          4.lambda表达式          5.override ...

  8. C++11新特性——range for

    很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ...

  9. C++11新特性之六——元编程

    C++11新特性之六——元编程

  10. C++11新特性之一——Lambda表达式

    C++11新特性总结可以参考:http://www.cnblogs.com/pzhfei/archive/2013/03/02/CPP_new_feature.html#section_6.8 C++ ...

随机推荐

  1. 获取linux服务器基本信息脚本

    为了方便日常运维写的一段简单脚本,用于集中获取服务器操作系统.CPU.内存使用.负载.硬盘使用.网络信息. 脚本比较简单,就不解释了,有兴趣的朋友请自行查看. #!/bin/bash##Name:sy ...

  2. 去除Jsp页面空白行

    在Jsp页面head位置添加 <%@ page trimDirectiveWhitespaces="true" %> 在项目web.xml中添加 <servlet ...

  3. org.springframework.context.ApplicationContextAware使用理解

    一.这个接口有什么用? 当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean.换句话说,就是这个类可以 ...

  4. 使用requireJS的shim参数 解决插件 jquery.ui 等插件问题

    没有requireJS框架之前,如果我们想使用jquery框架,会在HTML页面中通过<script>标签加载, 这个时候jquery框架生成全局变量$和jQuery等全局变量.如果项目中 ...

  5. transformjs:让天下没有难做的生意!不对,是特效!

    写在前面 transform是css3新增的一个属性,可是令开发者费解的是,其内部又有大量的属性如旋转.缩放.扭曲.平移,这也就导致了获取或者是设置transform中一个或者多个属性变得异常麻烦. ...

  6. CSS3图片翻转切换案例及其中重要属性解析

    图片翻转切换,在不使用CSS3的情况下,一般都是使用JS实现动画,同时操作元素的width和left,或者height和top以模拟翻转的效果,并在适当时候改变src或者z-index实现图片切换. ...

  7. H5中的touch事件

    touch中共有touchstart.touchmove和touchend三个事件: touchstart:触摸开始的时候触发 touchmove:手指在屏幕上滑动的时候触发 touchend:触摸结 ...

  8. iOS 大文件断点下载

    iOS 在下载大文件的时候,可能会因为网络或者人为等原因,使得下载中断,那么如何能够进行断点下载呢? // resumeData的文件路径 #define XMGResumeDataFile [[NS ...

  9. iOS RunLoop简介

    一.什么是RunLoop? RunLoop是运行循环,每个Cocoa应用程序都由一个处于阻塞状态的do/while循环驱动,当有事件发生时,就把事件分派给合适的监听器,如此反复直到循环停止.处理分派的 ...

  10. 源码安装ipython,并在ipython中整合spark

    一.安装ipython 下载ipython, https://pypi.python.org/packages/source/i/ipython/ipython-2.2.0.tar.gz#md5=b9 ...