STL容器之map使用, unordered_map区别,C++11中auto遍历用法,以及algorithm算法库中for_each的使用方法
C++11 for循环新用法
参考:
C++11中引入的auto主要有两种用途:自动类型推断和返回值占位
- auto在C++98中的标识临时变量的语义,由于使用极少且多余,在C++11中已被删除。
-
前后两个标准的auto,完全是两个概念。
- 使用auto
- 临时变量 auto member : mapStudent
- 引用 auto &member : mapStudent
- 可以用类型修饰符const指定只读 const auto &member : mapStudent
-
使用迭代器
-
使用for_each
使用for_each时定义的函数入参遇到的问题,应使用 std::pair<const int, MyClass>&,注意const的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//test_auto.cpp
#include <iostream>
#include <map>
#include<algorithm> //for_each使用
using namespace std;
void funcStudent(std::pair<const int, string> &pair);
int main(int argc, const char *argv[])
{
std::map<int, string> mapStudent;
mapStudent[1] = "lilei";
mapStudent[2] = "zhangsan";
cout << "======= auto& test case =========" << endl;
// member此处是引用类型,如果要限定语句块中不允许修改,可以使用类型修饰符const指定: const auto &
for (auto &member : mapStudent)
{
member.second = "x";
}
// 打印结果各成员已修改为"x"
for (auto member : mapStudent)
{
cout << member.second << endl;
}
cout << "======= auto test case =========" << endl;
mapStudent.clear();
mapStudent[1] = "lilei";
mapStudent[2] = "zhangsan";
// member此处是临时变量类型,语句块内赋值并不影响mapStudent原始成员值
for (auto member : mapStudent)
{
member.second = "x";
}
// 打印结果各成员还是与之前一样
for (auto member : mapStudent)
{
cout << member.second << endl;
}
// 演示迭代器用法
cout << "========= iterator test case =========" << endl;
for (std::map<int, string>::iterator iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
cout << iter->second << endl;
}
cout << "========= for_each test case =========" << endl;
// 演示for_each遍历map
std::for_each(mapStudent.begin(), mapStudent.end(), funcStudent);
// 打印结果各成员已修改为"123"
for (auto member : mapStudent)
{
cout << member.second << endl;
}
return 0;
}
// for_each传入函数,错误,入参并不是迭代器
// 编译报错: /usr/local/include/c++/4.8.5/bits/stl_algo.h:4417:14: 错误:将类型为‘std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char> > >&’的引用初始化为类型为‘std::pair<const int, std::basic_string<char> >’的表达式无效
// void funcStudent(std::map<int, string>::iterator mapStudent)
// {
// mapStudent->second = "123";
// }
// for_each传入函数,错误,
// 编译报错: /usr/local/include/c++/4.8.5/bits/stl_algo.h:4417:14: 错误:将类型为‘std::pair<int, std::basic_string<char> >&’的引用初始化为类型为‘std::pair<const int, std::basic_string<char> >’的表达式无效__f(*__first);
// void funcStudent(std::pair<int, string> &pair)
// {
// pair.second = "123";
// }
// for_each传入函数,解引用时, std::map iterator返回std::pair<const key_type, value_type>,
// 而不是 std::pair<key_type, value_type>,所以key需要const修饰
void funcStudent(std::pair<const int, string> &pair)
{
pair.second = "123";
}
编译执行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[xd@localhost ~/workspace/src]$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
# gcc 版本 4.8.5 (GCC)
[xd@localhost ~/workspace/src]$ g++ test_auto.cpp -std=c++11
[xd@localhost ~/workspace/src]$ ./a.out
======= auto& test case =========
x
x
======= auto test case =========
lilei
zhangsan
========= iterator test case =========
lilei
zhangsan
========= for_each test case =========
123
123
unordered_map
hash_map ≈ unordered_map
从 C++ 11 开始,hash_map 实现已被添加到标准库中。但为了防止与已开发的代码存在冲突,决定使用替代名称 unordered_map。这个名字其实更具描述性,因为它暗示了该类元素的无序性。
和map比较
新版的hash_map都是unordered_map了,这里只说unordered_map和map.
1
2
3
运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列。
占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。
需要无序容器,快速查找删除,不担心略高的内存时用unordered_map;有序容器稳定查找删除效率,内存很在意时候用map。
map的内部实现是二叉平衡树(红黑树);hash_map内部是一个hash_table