stl中set和map总结

set

1.set的迭代器是constant iterators,也就是说,不能通过迭代器修改set元素值。

2.自动排序。不允许两个元素有相同值。

3.插入新的元素和删除元素,不会造成旧的迭代器失效

4.底层是红黑树。它的功能基本上就是调用底层红黑树的接口。

set的模板参数是:

template <class Key, class Compare = less<Key>, class Alloc = alloc>

而rb_tree的模板参数是

template <class key_type, class value_type, class KeyOfValue, class key_compare, class Alloc>

rb_tree的key_type和value_type都取set的Key,而KeyOfValue则使用identity<value_type>(即返回自身),key_compare则取自set的Compare。

5.set的insert操作,如果参数是数字,返回的就是一对pair,如果成功插入(原树中没有这个数字),first是插入位置的迭代器,second是true;否则,first是原树中这个数字所在位置的迭代器,second是false。

set使用红黑树的insert_unique操作而不是insert_equal操作。因为它不允许两个元素有相同值。

set有接受一个迭代器范围的构造函数,它实际上就是调用了insert_equal操作,把它们挨个插进红黑树里面。

6.底层红黑树返回的都不是constant iterator,所以为了上面的第1条,要经常做强制类型转换,转换成const iterator。同样,向红黑树中传递迭代器参数时,也要进行强制类型转换,因为红黑树的函数都只接受非const的iterator。

7.set有key_compvalue_comp两个函数,它们实际上返回的都是模板中提供的Compare类型。

8.set自己的find函数比stl算法的find函数高效

map

1.map的迭代器比较特别,既不是constant的,也不是mutable的。map中的键是不能修改的,但值是可以修改的。

2.自动排序。不允许两个元素的有相同值。

3.插入新的元素和删除元素,不会造成旧的迭代器失效

4.底层是红黑树。它的功能基本上就是调用底层红黑树的接口。

map的模板参数是:

template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>

而rb_tree的模板参数是

template <class key_type, class value_type, class KeyOfValue, class key_compare, class Alloc>

rb_tree的key_type就是Key,而value_type是pair<const Key, T>(注意这里的const),KeyOfValue是select1st<value_type>,它取的是value_type的first。key_compare是Compare。

5.map的insert操作,如果参数是数字,返回的就是一对pair,如果成功插入(原树中没有这个数字),first是插入位置的迭代器,second是true;否则,first是原树中这个数字所在位置的迭代器,second是false。

map使用红黑树的insert_unique操作而不是insert_equal操作。因为它不允许两个元素有相同值。

map有接受一个迭代器范围的构造函数,它实际上就是调用了insert_equal操作,把它们挨个插进红黑树里面。

6.底层红黑树返回的都不是constant iterator,所以为了上面的第1条,要经常做强制类型转换,转换成const iterator。同样,向红黑树中传递迭代器参数时,也要进行强制类型转换,因为红黑树的函数都只接受非const的iterator。

7.map有key_compvalue_comp两个函数。key_comp返回的就是模板中提供的Compare类型对象。而map自定义了一个仿函数类value_compare,它重载的()符号,实际上就是对first调用了Compare。value_comp返回的是value_compare类型对象。

8.map自己的find函数比stl算法的find函数高效

9.map重载了[]符号

T& operator[] (const key_type& k) {
	return (*((insert(value_type(k, t()))).first)).second;
}

这里的T,实际上就是键值对中值的类型
从内向外读,首先是insert(value_type(k, t())),插入的键值对value的键来自形参k,而值是T类型默认构造的。
然后insert操作返回的是pair<iterator, bool>类型,所以用first取出迭代器:(insert(value_type(k, t()))).first
然后对迭代器解引用*((insert(value_type(k, t()))).first),得到的是value_type类型。
value_type类型也是pair类型(键值对),所以取出它的second,就是值。返回的是这个值。

注意这里operator[]的返回值是引用类型,而对于insert操作,如果map中没有要插入的值,就插入并返回插入位置的迭代器,如果要插入的值已经存在了,就直接返回原来位置的迭代器。所以这个操作符既可以当左值使用,也可以当做右值使用。

map<string, int> simap;
simap[string("jjhou")] = 1; // 左值运用
...
int number = simap[string("jjhou")] // 右值运用

multiset

1.允许键值重复,所以它和set的唯一区别是使用insert_equal而不是insert_unique

multimap

1.允许键值重复,所以它和map的区别之一是使用insert_equal而不是insert_unique

2.不能使用[]符号来做插入

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值