Effective STL
扮猪吃饺子
努力的人,运气不会太差。
展开
-
26 iterator优于const_iterator、reverse_iteratorj及const_reverse_iterator
有些版本的insert和erase函数要求使用iterator。如果你需要调用这些函数,那么必须使用iterator。const和reverse型的迭代器不能满足这些函数要求。要想隐式将一个const_iterator转换成iterator式不可能的从reverse_iterator转换而来的iterator在使用前需要调整。如下图:...原创 2018-07-04 10:29:09 · 701 阅读 · 0 评论 -
40 若一个类是函数子,则应是它可配接
例如:list<Widget*> widgetPtr;bool isInteresting(const Windget* pw);//若想找到第一个满足isInteresting条件的Widget指针:list<Widget*>::iterator it = find_if(widgetPtr.begin(),widgetPtr.end(), i...原创 2018-07-05 10:11:16 · 137 阅读 · 0 评论 -
41 理解ptr_fun、mem_fun和mem_fun_ref的由来
mem_fun:针对指针容器中调用成员函数mem_fun_ref:针对对象容器中调用成员函数ptr_fun:针对一般函数的调用,(可有可无,在not1 not2等配接的时候就要加上ptr_fun)mem_fun和mem_fun_ref相当于将成员函数转换成一般函数调用。 ,...原创 2018-07-05 10:12:13 · 391 阅读 · 0 评论 -
42 确保less《T》与operator《具有相同语意
题目上less《T》、operator《应该是less<T>和operator<。因为csnd题目上不能用<作为一般规则,对于std名字空间的组件进行修改是确实被禁止的,但是某些特定情况下,有些对std名字空间的修补工作是被允许的,特别是是,程序员可以针对用户自定义类型,特例化std中的末班。尽量避免修改less行为,因为这样做可能会误导其他的程序员。如果你使用了less。...原创 2018-07-05 10:17:37 · 252 阅读 · 0 评论 -
43 算法调用优先于手写的循环
理由:1.效率:算法通常比程序员自己写的循环效率更高2.正确性:自己写循环比使用算法更容易出错3.可维护性:使用算法代码通常比手写循环的代码更加简洁明了例如假如有一个数组(可能由于某个遗留下来的C API的原因),而你要让每个数组元素加上41,然后插入到一个deque的前部。自己编写循环://输入参数是一个指向double数组的指针和该数组的大小//在函数中,将向这个数组写入数据,它的返回值实际...原创 2018-07-05 10:19:40 · 212 阅读 · 0 评论 -
44 容器的成员函数优先于同名的算法
成员函数往往速度快。成员函数通常与容器(特别是关联容器)结合的更加紧密。关联容器,假设一个set容,其中包含一百万个值,现在查找727这个值是否包含在容器中set<int> s; //创建set,并放入一百万个值...set<int>::iterator it = s.find(727); //使用find成员函数if(it != s.end())...原创 2018-07-05 10:21:21 · 158 阅读 · 0 评论 -
45 正确区分count、find、binary_search、lower_bound、upper_bound和equal_range
比如:我们假定你有一个迭代器,他们指定了一个被搜索的区间。在选择具体的查找策略时,由迭代器指定的区间是否排序的,这是一个至关重要的决定条件:1.如果区间是排序的,那么通过binary_search、lower_bound、upper_bound和equal_range,你可以获得更加快的查找速度(通常是对数时间的效率)。2.如果迭代器没有指定一个排序的区间,那么你选择范围将局限于count、cou...原创 2018-07-05 10:27:12 · 1062 阅读 · 0 评论 -
46 考虑使用函数对象而不是函数作为STL算法的参数
使用函数对象效率高(大多数编译器不会针对函数指针执行的函数进行内联优化,即时加了inline)让你的正确正确被编译这样有助于避免一些微妙的、语言本身的缺陷在新的编译器下,后两条用函数一样是正确的。书中例,将一个集合中每一个字符串对象长度输出到cout中,是可以通过编译并且运行的:(我用的是支持C++11的编译器,可能以前老版本的不行) std::set<std::string> s =...原创 2018-07-06 09:44:45 · 221 阅读 · 0 评论 -
47 避免产生“直写型”(write-only)的代码
假定有一个vector<int>,现在想删除其中所有的其值小于x,的元素,但是,最后一个其值不小于y的元素之前的所有元素应该保留下来: vector<int> v = {1,2,3,4,5,5,6,6,6,7,7,7,8,8,8}; v.erase( remove_if(find_if(v.rbegin(),v.rend(), bind2nd(grea...原创 2018-07-06 09:46:26 · 500 阅读 · 0 评论 -
48 总是包含(#include)正确的文件
总结:几乎所有的标准STL容器都被声明在与之同名的头文件中。除了4个STL算法以外,其他算法都声明在<algorithm>中,这四个算法是accumulate、inner_product、adjacent_difference和partial_sum,他们被声明在<numeric>中。特殊类型的迭代器,包含istream_iterator和istreambuf_iterat...原创 2018-07-06 09:46:51 · 145 阅读 · 0 评论 -
49 学会分析与STL有关的编译器诊断信息
STL内部使用的模板:string为basic_string、map为_Tree或者_rb_tree在一个呗声明为const的成员函数内部,该类的所有非静态数据成员自动被转化变成相应的const类型。vector和string的迭代器通常是指针,所以错误地使用iterator时,编译器信息中可能会引用到指针类型。如果诊断信息提到了back_insert_iterator、front_insert_...原创 2018-07-06 09:47:11 · 128 阅读 · 0 评论 -
39 确保判别式是“纯函数”
一个判别式是一个返回值为bool类型(或者可以隐式转换成bool类型的)函数。一个纯函数是指返回值仅仅依赖其参数的函数,例如:假设f是一个纯函数,x,y是两个对象,那么只有x或者y发生变化时,f(x,y)返回值才可能发生变化。在C++中,纯函数所能访问的数据仅局限于参数以及常量(在函数生命周期内不会被改变,这个常量数据应该声明称const)STL中凡是需要判别式函数的地方,既可以接受一个真正的函数...原创 2018-07-05 10:09:40 · 171 阅读 · 0 评论 -
38 遵循按值传递的原则来设计函数子
C/C++的标准库函数遵循的规则:函数指针按值传递的由于函数对象往往按值传递和返回的,所以,你编确保编写的函数对象在经过传递后还能正常工作。意味着:1、首先,你的函数对象必须尽可能的小,否则拷贝开销会非常大2、函数对I想不能是多态的,即不能是虚函数。(传递过程中会产生剥离问题)解决多态的函数子的方法:将所需的和虚函数从函数子类中分离出来,放到一个新的类中;然后再函数子类中包含一个指针,指向这个新类...原创 2018-07-05 10:09:04 · 150 阅读 · 0 评论 -
37 使用accumulate或者for_each进行区间统计
1.count告诉你一个区间有多少个元素,count_if统计满足判别式的元素个数。2.区间的最大值和最小值分别为max_element和max_element.算法accumulate 和 inner_product、adjacent_differenthe和partial_sum 头文件是<numeric>区间统计处理:可能计算一个区间的数值的乘积;计算一个区间的平均坐标等。...原创 2018-07-05 09:51:36 · 185 阅读 · 0 评论 -
27 使用distance和advance将容器的const_iterator转换成iterator
大多数情况下,将const_iterator强制转换成iterator不能通过编译,利用const_cast、reinterpret_cast、static_cast 甚至C语言的强制类型转换。对于vector和string也许能通过编译,只针对const_iterator,而reinterpret_cast、static_cast仍然不行。可以使用advance和distance将const_i...原创 2018-07-04 10:31:23 · 394 阅读 · 0 评论 -
28 正确理解由reverse_iterator的base()成员函数所产生的iterator的用法
对于下面的一段代码:vector<int> v;v.reserve(5);for(int i = 0;i < 5;++i){v.push_back(i);}vector<int>::reverse_iterator ri = find(v.rbegin(),v.rend(),3);vector<int>::iterator i(ri.base());执行上...原创 2018-07-04 10:34:16 · 310 阅读 · 0 评论 -
29 对于逐字符 的输入请考虑使用istreambuf_iterator
如果你需要从一个输入流中逐个读取字符,那么不必使用格式化输入;如果你关心的读取流的时间开销,那么使用istreambuf_iterator取代istream_iterator只多输入了三个字,却可以获得明显的性能改善。对于非格式化的逐个字符输入过程,你总应该考虑使用istreambuf_iterator。对于非格式化的逐个字符输出过程,你也考虑使用ostreambuf_iterator.它可以避免...原创 2018-07-04 10:37:28 · 545 阅读 · 0 评论 -
30 确保目标区间足够大
...原创 2018-07-04 10:39:08 · 172 阅读 · 0 评论 -
31 了解各种与排序有关的选择
如果需要对vector、string、deque或者数组的元素执行一次完全排序,那么可以使用sort或者stable_sort。如果有一个vector、string、deque或者数组,并且只需要对等价性最前面的n个元素进行排序,那么可以使用partial_sort。如果有一个vector、string、deque或者数组,并且需要找到第n个位置上的元素,或者,需要找到等价性最前面的n个元素蛋不必...原创 2018-07-04 10:39:50 · 145 阅读 · 0 评论 -
32 如果确实需要删除元素,则需要在remove这一类算法之后调用erase
remove不是真正意义上的删除,因为它做不到。remove并不知道它的具体容器类型,只接受迭代器类型。remove移动了区间中的元素,其结果是,“不要被删除”的元素移动到了区间的前面(保持原有的相对顺序),它返回的一个迭代器只想最后一个“不用背删除”的元素之后的元素,这个返回值相当于该区间的“新的逻辑结尾”。所以如果要删除元素,要配合使用remove和erase:vector<int>...原创 2018-07-04 10:40:43 · 187 阅读 · 0 评论 -
33 对包含指针的容器使用remove这一类算法时要特别小心
因为删除容器中的指针并不能删除该指针指向的对象。造成资源泄露!!!对包含指针的容器的处理:或者通过引用计数的智能指针,或者调用remove算法之前手动删除指针并将他们置为空,或者用你自己发明的其他技术。本条款的指导原则是:对包含的指针的容器使用remove类算法需要特别警惕,如果你不留意这条警告,其后果就会造成资源泄露。...原创 2018-07-04 10:43:12 · 150 阅读 · 0 评论 -
34 了解哪些算法要求使用排序的区间作为参数
要求排序区间的STL算法:binary_search:如果找到返回true,否则返回false原型:template <class ForwardIterator, class T> bool binary_search ( ForwardIterator first, ForwardIterator last, const T& ...原创 2018-07-04 10:44:16 · 176 阅读 · 0 评论 -
35 通过mismatch或者lexicographical_compare实现忽略大小写字符串的比较
使用mismatch:int ciCharCompare(char c1,char c2){ int lc1 = tolower(static_cast<unsigned char>c1); int lc2 = tolower(static_cast<unsigned char>c2); if(lc1 < lc2) return -1; if(lc1 > l...原创 2018-07-04 10:44:58 · 241 阅读 · 0 评论 -
36 理解copy_if算法的正确实现
copy_if 在STL中没有实现,复制区间满足某个判别式的所有元素,需要自己来实现。注:C++11中已经自带copy_if算法代码如下:#include <iostream>#include <algorithm>#include <string>#include <vector>using namespace std;bool isDefecti...原创 2018-07-05 09:49:10 · 268 阅读 · 0 评论 -
50 熟悉与STL相关的Web站点
SGI STL站点:www.sgi.com/tech/stl/ (已经被移除了)STLport站点: www.stlport.orgBoost站点:www.boost.org原创 2018-07-06 09:47:30 · 206 阅读 · 0 评论