有些STL 容器提供了一些与算法同名的成员函数。大多数情况下,应该使用这些成员函数,而不是相应的STL算法。 有两个理由:
- 成员函数往往速度快。
- 成员函数通常与容器结合地更紧密,这是算法所不能比的。
set容器的find成员函数以对数时间运行,而find算法以线性时间运行。
效率并不是find成员函数和find算法之间的唯一差别。STL算法以相同性而判断两个对象是否具有相同的值,而关联容器使用等价性来进行它们的"相同性"测试。因此,在使用关联容器的时候,应该优先考虑成员函数形式的find、count、lower_bound等,而不是相应的STL算法,这些成员函数的行为与关联容器的其他成员函数能够保存更好的一致性。由于相等性和等价性之间的差别,STL算法不可能提供这样的一致性。
对于标准的关联容器,选择成员函数而不选择对应的同名算法,这可以带来几方面的好处。
- 可以获得对数时间的性能,而不是线性时间的性能。
- 可以使用等价性来判断的那个两个值是否"相同",而等价性是关联容器的一个本质定义。
- 在使用map和multimap的时候,将很自然地只考虑元素的键部分,而不是完整的键值对。
对于list,性能几乎成为了全部考虑元素。
remove、remove_if、unique、sort、merge以及reverse这些算法无一例外地需要拷贝list容器的对象,而这些版本的成员函数则无需任何对象拷贝,它们只是简单地维护好那些将list节点连接起来的指针。这些算法的时间复杂度并没有改变,但多数情况下维护指针的开销比拷贝对象要低得多,所以list成员函数应该会提供更好地性能。
list成员函数的行为不同于其同名的算法。如果真的要从容器中删除对象的话,在调用remove、remove_if或者unique算法之后,必须接着调用erase。而list的remove、remove_if、unique成员函数则实实在在地删除了元素,所以无需再调用erase。
sort算法与list的sort函数之间一个很重要的区别是,前者根本不能被应用于list容器上,list的迭代器只是双向迭代器,而sort算法要求随机访问迭代器。在merge算法和list的merge成员函数之间也存在这种区别。merge算法是不允许修改其源区间的,而list的merge成员函数总是在修改它所操作的链表。
当需要在STL算法与容器的同名成员函数之间做出选择的时候,应该优先选择成员函数。成员函数的性能更为优越,而却它们更能够与容器的一贯行为保持一致。