44.以成员函数代替同名算法

前言

 
有些容器提供了与泛型算法相同名称的成员函数,比如关联容器提供了count、find、lower_bound、upper_bound和equal_range,
而list提供了remove、remove_if、unique、sort、merge、reverse。
我们提倡使用成员函数代替同名算法,第一是因为它们的结合性更好,第二是因为它们更快。


关联容器

set

假设我们需要在一个容纳了百万元素的set中查找727的位置:

1
2
3
set<int> s; // 建立set,放入1,000,000个数据
auto i = s.find(727); //使用find成员函数
auto i = find(s.begin(), s.end(), 727); // 使用find算法

find成员函数消耗对数时间,而泛型算法消耗线性时间。原因在于set基于红黑树,红黑树的查找操作只需要对数时间。(完全平衡树所需要的时间更短,但总体效率差于红黑树)

效率并不是唯一的差别,众所周知,STL算法判同基于相等,而关联容器是基于等价,因此查找算法可能会返回给你不同的结果。为了行为一致,我们应该更倾向于使用成员函数。

map

泛型算法及其不适用于map与multimap,因为它们内部元素是pair,因此count成员函数只统计key匹配的pair数目,find等成员函数也是如此,但是泛型算法会使用相等性测试来统计具有相同键和值的pair对象的个数。如果你只希望检查key,那你只能在vector内部存pair代替关联容器。(Effective STL 23)


list

 
对于list而言,使用成员函数最大的提升在于效率。list的成员函数不进行任何拷贝,它们只是简单地操纵连接list节点的指针。算法和它所使用的时间复杂度相同,但是算法需要拷贝。
另外,list成员函数的行为可能与算法并不一样,list的remove或unique等函数无需执行erase.
sort算法不能用于list的双向迭代器,merge算法不能修改源范围,但list的同名成员函数可以。