几个概念
一元函数:函数的参数只有一个
一元断言(谓词):一元的函数返回类型是bool
二元函数:函数的参数只有两个
二元断言(谓词):二元的函数返回类型是bool
1、for_each()
void print(int &number)//一元函数
{
++number;
cout << number << " ";
}
void test()
{
vector<int> numberVec = {1, 3, 5, 7, 9, 4, 6, 7};
//把numberVec从头到尾每个元素都交给print()
for_each(numberVec.begin(), numberVec.end(), print);//前两个参数用于表示容器范围,第三个参数必须是一元函数
//也可以写成下面这样,[]表示匿名函数,Lambda表达式
for_each(numberVec.begin(), numberVec.end(),[] (int &number)
{
++number;
cout << number << " ";
});
cout << endl;
}
2、remove_if()
bool func(int number) //一元断言
{
return number > 4;
}
void test()
{
vector<int> numberVec = {1, 3, 7, 8, 1, 2, 5, 7, 9, 4, 6, 7};
copy(numberVec.begin(), numberVec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << endl;
//it前的是要保留的,it及之后的是不要的
auto it = remove_if(numberVec.begin(), numberVec.end(), func);
copy(numberVec.begin(), numberVec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
numberVec.erase(it, numberVec.end());//删除it及it后的元素
copy(numberVec.begin(), numberVec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
源码:
template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
first = std::find_if(first, last, p);
if (first != last)
{
for(ForwardIt i = first; ++i != last; )
{
if (!p(*i))
{
*first++ = std::move(*i);
}
}
}
return first;
}
template<class InputIt, class UnaryPredicate>
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first)
{
if (p(*first))
{
return first;
}
}
return last;
}
first last
1, 3, 7, 8, 1, 2, 5, 7, 9, 4, 6, 7
p(7)==1,return first // first = std::find_if(first, last, p);first last
1, 3, 7, 8, 1, 2, 5, 7, 9, 4, 6, 7
i
// for(ForwardIt i = first; ++i != last; ) ,
p(8)==1, ++i;
p(1)==0, *first++ = std::move(*i),++i;
first last
1, 3, 1, 8, 1, 2, 5, 7, 9, 4, 6, 7
i
p(2)==0, first++ = std::move(*i),++i;
first last
1, 3, 1, 2, 1, 2, 5, 7, 9, 4, 6, 7
i
p(5)==1, ++i;
p(7)==1, ++i;
p(9)==1, ++i;
p(4)==0. first++ = std::move(*i),++i;
first last
1, 3, 1, 2, 4, 2, 5, 7, 9, 4, 6, 7
i
p(6)==1, ++i;
p(7)==1, ++i;
return first;
//使用匿名函数的形式进行第三个参数的替换
auto it = remove_if(numberVec.begin(), numberVec.end(), [](int number)
-> bool {
return number > 4;
}
);
//-> bool只是为了表明return的类型,可写可不写
3、find()和count()
void test()
{
vector<int> numberVec = {1, 3, 5, 7, 9, 4, 6, 7};
copy(numberVec.begin(), numberVec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
size_t cnt1 = count(numberVec.begin(), numberVec.end(), 7);
cout << "cnt1 = " << cnt1 << endl;
auto it = find(numberVec.begin(), numberVec.end(), 3);
if(it == numberVec.end())
{
cout << "该元素不存在vector中" << endl;
}
else
{
cout << "该元素存在vector中" << *it << endl;
}
}
4、mem_fn()
目的:使成员函数也可以用于算法函数:for_each()、remove_if()等
class Number
{
public:
Number(size_t data = 0)
: _data(data)
{
}
void print() const
{
cout << _data << " ";
}
private:
size_t _data;
};
void test()
{
vector<Number> numbers;
for(size_t idx = 1; idx != 30; ++idx)
{
numbers.push_back(Number(idx));
}
//把numbers从头到尾每个元素都交给Number::print()
std::for_each(numbers.begin(), numbers.end(), mem_fn(&Number::print));
/* std::for_each(numbers.begin(), numbers.end(), &Number::print); //这么写会有bug*/
cout << endl;
}