###C++ Primer第5版 学习笔记
####第十章
下面说的算法都是本章的泛型算法
- 迭代器令算法不依赖于容器,但算法依赖于元素类型的操作,一般也有重载函数允许我们自己提供谓词函数代替默认的运算符
- 算法自身永远不会执行容器的操作,永远不会改变底层容器的大小
- accumulate 第三个参数的类型决定了使用哪个加法运算符和返回值类型,
auto sumstring = accumulate(strvec.cbegin(), strvec.end(), "");
会尝试使用 const char* 的加运算符,导致编译错误 - 算法不检查写操作,fill_n, copy 函数对木渎位置的有效性不做判断
- lambda 表达式有点像一个重载了函数调用运算符的类,在声明 lambda 时,先用捕获列表初始化该类的对象,调用 lambda 时,调用该对象的函数调用操作并传入参数
- lambda 可以忽略参数列表和返回类型,但必须有捕获列表和函数体
auto f = [] { return 42; };
- 只能对 lambda 所在函数中定义的(非 static)变量使用捕获列表,但定义在当前函数之外的名字可以直接使用
- 与参数不同,被捕获的变量是在 lambda 创建时拷贝
- 如果某函数返回 lambda,本质是返回一个没有名字的类的对象(包含数据),因此若此对象中含有临时对象的引用,则无效,因此作为函数返回值的 lambda 不应含有引用捕获
- 如果 lambda 体内包含 return 语句之外的任何语句,则编译器假定返回 void,往往需要自己写明返回类型,且只能使用尾置返回类型
- bind 是一个函数适配器,一般用在将某需要若干参数的函数改造成只需要几个参数以作为某泛型算法谓词的函数, bind拷贝其参数,因此要使用 ref 或 cref 生成一个保存引用的类,使用
_n
时需using namespace std::placeholders
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
using namespace std;
using namespace std::placeholders;
bool f(const string &s, int i, vector<string> &r) {
if (s.length() == i) {
r.push_back(s);
return true;
}
return false;
}
int main()
{
vector<string> vs, r;
copy(istream_iterator<string>(cin), istream_iterator<string>(), back_inserter(vs));
cout << count_if(vs.begin(), vs.end(), bind(f, _1, 5, ref(r)));
copy(r.begin(), r.end(), ostream_iterator<string>(cout, " "));
cout << r.size();
}
- back_insert 使用 push_back,front_insert 使用 push_insert,insert 使用 insert,自己会在插入后调整位置保证一直在第二个参数之前插入