1、find、count、accumulate、equal
accumulate的第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型
vector<string> svec1;
vector<double> dvec2;
string sum = accumulate(svec1.cbegin(), svec1.cend(), string("")); // 正确
string sum = accumulate(svec1.cbegin(), svec1.cend(), ""); // 错误 ""是const char*型 此类型没有 + 运算符
auto sum2 = accumulate(dvec2.cbegin(), dvec2.cend(), 0); // sum2是int类型 因为第三个参数 0 是int
equal基于一个非常重要的假设:它假定第二个序列至少与第一个序列一样长。
vector<double> vec2{1,2,3,4,5,6};
bool e1 = equal(vec1.cbegin(), vec1.cend(), vec2.cbegin());// e1为true
bool e2 = equal(vec2.cbegin(), vec2.cend(), vec1.cbegin());//运行时错误 vec1比vec2短
2、back_inserter、copy、replace、replace_copy
list<int> lst{ 1,3,5,8,8,8,9 };
vector<int> vec;
replace_copy(lst.begin(), lst.end(), back_inserter(vec), 8, 7);
printvec(lst); //1,3,5,8,8,8,9
printvec(vec); //1,3,5,7,7,7,9
3、sort、unique
unique会将相邻的重复项用后面不重复的项覆盖
vector<int> vec{ 1,3,5,3,6,4,5,2 };
sort(vec.begin(), vec.end(), [](int a, int b) {return a > b;});
printvec(vec); // 6 5 5 4 3 3 2 1
unique(vec.begin(), vec.end());
printvec(vec);// 6 5 4 3 2 1 2 1
4、习题10.13
vector<string> vec{ "abcde", "12", "333", "55555", "4444", "666666" };
auto itr = partition(vec.begin(), vec.end(), [](string& str) {return str.size() >= 5;});
for (auto itrs = vec.begin(); itrs != itr; ++itrs)
{
cout << *itrs << endl;
}
5、lambda表达式
- lambda不能有默认参数
- 值捕获的前提是变量可拷贝,拷贝发生在lambda创建时,而不是一般函数的调用时
6、指定lambda的返回类型,与书上说的不太一样
vector<int> v1{ 1,-3,-4,2,-5 };
transform(v1.begin(), v1.end(), v1.begin(), [](int i) {return i < 0 ? -i : i;});
//书上说这里必须显示指定lambda返回值 否则编译失败 但我这里vs和g++都编译通过了
transform(v1.begin(), v1.end(), v1.begin(), [](int i) {if (i < 0)return -i; else return i;});
7、bind
bind接受一个可调用对象,生成一个新的可调用对象。
// g是一个有两个参数的函数 例如 调用g(x,y) 会调用 f(a,b,y,c,x)
auto g = bind(f, a, b, placeholders::_2, c, placeholders::_1);
默认情况下,bind的哪些不是占位符的参数被拷贝导bind返回的可调用对象中。但是,与lambda类似,有时对有些绑定的参数我们希望以引用的方式传递,或是要绑定参数来的类型无法拷贝。此时需要用到ref或cref
ostream &print(ostream &os, const string& s)
{
return os << s;
}
void test()
{
vector<string> vec;
for_each(vec.begin(), vec.end(), bind(print, os, placeholders::_1)); //错误 不能拷贝os
for_each(vec.begin(), vec.end(), bind(print, ref(os), placeholders::_1)); //正确
}
8、流迭代器
string str = "abcde";
ostream_iterator<char> out_itr(cout, ", ");
for (char c : str)
*out_itr++ = c;
cout << endl;
copy(str.begin(), str.end(), out_itr);
使用copy来遍历打印str的内容,很有意思~
9、习题10.30 使用流迭代器、sort、copy从标准输入读入一个整数序列,排序,输出到标准输出
vector<int> vec;
istream_iterator<int> in(cin), eof;
copy(in, eof, back_inserter(vec));
sort(vec.begin(), vec.end());
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, ", "));
cout << endl