C++ Primer 第10章 知识点回顾

10.2.2 写容器元素的算法

  1. 我们常常使用back_inserter来创建一个迭代器,作为算法的目的位置来使用fill_n(back_inserter(vec),10,0);(每次赋值都会在vec上调用push_back),使用back_inserter按需要增长目标序列

10.2.3 重排容器元素的算法

  1. 标准库算法对迭代器而不是容器进行操作,因此,算法不能直接添加或删除元素

10.3.1 向算法传递函数

  1. stable_sort可以维持相等元素的原有顺序

10.3.2 lambda表达式

  1. lambda必须包含捕获列表和函数体。若有返回类型,必须使用尾置返回。(lambda表达式表示一个可调用的代码单元)
auto f=[]{return 42};
cout<<f()<<endl;//输出42
transform(vi.begin(),vi.end(),vi.begin(),[](itn i)->{if(i<0) return -i;else return i;});
  1. 一个lambda只有在其捕获列表中捕获一个他所在函数中的局部变量,才能在函数体中使用该变量
  2. 捕获列表值用于局部非static变量,lambda可以直接使用局部static变量和在他所在函数之外声明的名字
  3. stable_partition: 在划分后的序列中维持原有元素的顺序

10.3.3 lambda捕获和返回

  1. 当定义一个lambda时,编译器生成一个与lambda对应的新的未命名的类类型
  2. auto f=[]{return 42;};//定义了一个从lambda生成的类型的对象
  3. 值捕获:lambda**创建时**拷贝变量,而不是调用时拷贝。
  4. 当以引用方式捕获一个变量时,必须保证在lambda执行时变量是存在的
  5. 一般来说,应该疆良减少捕获的数据量,来避免潜在的捕获导致的问题,而且,如果可能的话,应该避免捕获指针或引用
  6. 可变lambda:默认情况对于一个值被拷贝的变量,lambda不会改变其值。如果我们希望能改变一个呗捕获的变量的值,就必须在参数列表后加上关键字mutableauto f=[v1]()mutable{return ++v1;};一个引用捕获的变量是否可以修改依赖于此引用指向的是一个const类型还是一个非const类型
  7. 默认情况一个lambda体包含任何return之外的任何语句,编译器假定此lambda返回void。

10.3.4 参数绑定

  1. bind:它接受一个可调用对象,生成一个新的可调用对象来适应源对象的参数列表auto newCallable=bind(callable,arg_list);
  2. arg_list中参数包含形如_n是占位符,他们占据了传递给newCallable的参数的位置。例如:_1为newCallable的第一个参数。。。
  3. auto g=bind(f,a,b,_2,c,_1);//传递给g的参数按位置绑定到占位符:当我们调用g时,第一个参数传递给f作为最后一个参数。。
  4. 默认情况下,bind的那些不是占位符的参数被拷贝到bind返回的可调用对象中。如果我们希望传递给bind一个对象而又不拷贝他,必须使用标准库ref函数for_each(wors.begin(),words.end(),bind(print,ref(os),_1,' '));函数ref返回一个对象,包含给定的引用,此对象是可以拷贝的

10.4.1 插入迭代器

  1. inserter(lst3,lst3.begin());若lst={1,2,3,4},则lst3={1,2,3,4},而front_inserter插入完是4,3,2,1,即后者元素总是插入到容器第一个元素之前,而前者不是,前者总是在指定位置之前插入元素。

10.4.2 iostream迭代器

  1. istream_iterator读取输入流,ostream_iterator想输出流写数据,这些迭代器将他们对应的流当作一个特定类型的元素序列来处理。
  2. istream_iterator<int> int_in(cin);//从cin读取int
    istream_iterator<int> int_eof;//尾后迭代器
    ifstream("afile");
    istream_iterator<string> str_it(in);//从"afile读取字符串"

  3. while(in_iter!=eof)
    {
    vec.push_back(*in_iter++);//后置递增运算符读取流,返回迭代器的旧值,解引用迭代器,获得从流读取的前一个值
    }

  4. vector<int> vec(in_iner,eof);//由迭代器范围构造vec,这个构造函数从cin中读取数据,直至遇到文件尾或者一个不是int的数据为止。读取的数据被用来构造vec。

  5. accumulate(initer,eof,0);
  6. ostream_iterator<int> out_iter(cout," ");
    for(auto e:vec)
    out_iter=e;//*out_iter++=e,赋值时,写操作会被提交
    cout<<endl;

  7. copy(vec.begin(),vec.end(),out_iter);


10.4.3 反向迭代器

  1. sort(vec.rbegin(),vec.rend());//按逆序排序反向迭代器从序列尾部开始朝着序列首部移动,++riter使得迭代器在原始序列上从尾到头方向运动
  2. rcomma.base();此函数会返回反向迭代器对应的普通迭代器,rcomma和rcomma.base()必须生成相邻位置而不是相同的位置。
  3. vec.rbegin():指向尾元素的迭代器;vec.rend(): 指向首前元素的迭代器

10.5.1 5类迭代器

  1. 输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器

10.6 特定容器算法

  1. 通用版本的sort要求随机访问迭代器,因此不能使用与list和forward_list,因为这两个类型分别提供双向迭代器和前向迭代器。
  2. 对于链表,应该优先使用成员函数版本的算法而不是通用算法。(通过改变元素间的链接去操作,速度更快)
  3. 链表特有的操作会改变容器,链表版本会改变底层的容器

小结

  1. 当我们将一个容器元素类型的值赋予一个插入迭代器时,迭代器会将该值添加到容器中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值