c++ Primer学习完后第十章泛型算法的小结
泛型算法主要是针对容器的算法,利用迭代器对容器操作。要注意的是,泛型算法一般情况下不会直接操作容器,而是利用迭代器进行操作。这些算法都是定义在标准库中,可以看书中后面的附录A,选择需要的算法和相应的头文件。
这里就需要引入新名词,谓词。我理解额谓词,基本上就是一个bool类型的函数和lambda表达式(一个可调用对象),传递到算法中。谓词分为一元谓词和二元谓词(如果是函数的话,就是看形参有几个,有两个的话就是二元谓词)。有的算法只能接受一个一元谓词,但是有的时候就需要两个形参。这个时候就需要lambda表达式。
lambda表达式的格式如下:
[ ] () -> return type {};
[]:捕获列表,在调用lambda表达式的函数中,要使用这个函数的那个变量。里面可以为空,但是“[]”必须写。
():参数列表,与普通函数一样。可以不写。
return type :返回的类型。可以不写。
{}:函数体,与普通函数一样。必须有。
例子:
auto f = [] {return 42;};
cout << f() << endl;//返回42
需要注意的是,如果只有一句return语句的话auto是可以判断类型的,但是如果出了return语句之外还有其他的语句,那么auto就是自动判断为void类型,这个时候就需要指定类型,如 -> int 。
lambda的捕获列表,和函数形参差不多,会进行拷贝。但是与函数不同的是,捕获列表一开始就进行拷贝,函数是在调用的时候拷贝。意思就是lambda一但开始捕获变量,那么,那个变量一开始的值是多少,以后调用这个lambda那个变量的值一样。所以,lambda也是可以用引用来使用的,与函数的一样。
bind函数。一般的表达式:auto newfunction = bind(function,arg_list);
比起讲理论,还是直接上例子比较好理解吧。
假设一个函数bool jugsz(const string &s7,int sz);那么auto newjugsz = bind(jugsz,_1,6);
newjugsz(“fda”);相当于使用jugszsz(“fda”,6)。
bind里面的第一个参数就是要绑定的函数名,_1是newjugsz 要传入的第一个参数,sz就会默认是6。这样newjugsz也是可以是一个一元谓词。如果变成
auto newjugsz = bind(jugsz,_1,_2);那么newjugsz(_1,_2)相当于jugszsz(_1,_2)。如果auto newjugsz = bind(jugsz,_2,_1);那么newjugsz(_1,_2)相当于jugszsz(_2,_1)。如果要在bind里面引用的话,不能使用“&”,要用ref()。
5种迭代器,输入迭代器,输出迭代器,前向迭代器,双向迭代器,随机访问迭代器。算法调用迭代器会有限制。如果用了不符合类型的迭代器,会出现错误。除了输入迭代器和输出迭代器,其他三种是一种层次关系,或者说是子集关系。也就是说前向迭代器有的功能,双向迭代器都有,但是有一些功能双向迭代器有,而前向迭代器没有。
这里做一个小笔记。主要是想要有一个印象,以后有用到的话,如果想不起具体的用法再去查。
插入迭代器:back_iteratorer(调用push_back),front_iteratorer(调用push_front),iteratorer(使用insert成员函数)。
哦。对了。list和forward_list都有自己版本的算法。毕竟是链表。