36.自定义copy_if算法

(C++ 11 已经引入copy_if,本节虽过时,了解copy_if的实现也是好的)

前言

 
STL的一大奇特之处在于有11个关于copy的算法,但却没有名为copy_if的算法,也就是说如果你仅仅想要复制区间内某个符合条件的值的话,你得自己动手
image_1cbb8bpl0tsj1ho01qaiaj9bqf9.png-27.2kB


问题实例

 
假设我们有一个谓词判定widget是否有缺陷,然后把一个vector内所有有缺陷的Widget放进cerr,如果我们有copy_if的话:

1
2
3
bool isDefective(const Widget& w);
vector<Widget> widgets;
copy_if(widgets.begin(), widgets.end(),ostream_iterator<Widget>(cerr, "\n"), isDefective);


copy_if的具体实现

错误版本

大神们认为实现copy_if是微不足道的琐事,但这并不意味着对我等来说实现起来很容易,比如说下面这个(不正确的)具体实现:

1
2
3
4
5
template<typename InputIterator,typename OutputIterator, typename Predicate>
OutputIterator copy_if(InputIterator begin,InputIterator end,
OutputIterator destBegin, Predicate p){
return remove_copy_if(begin, end, destBegin, not1(p));
}

上述实现并不能用于函数中,因为not1不能直接作用于函数指针,最起码也得用一个std::function修饰一下。但算法不应该要求仿函数具有可适配性。

真正实现

1
2
3
4
5
6
7
8
9
template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if(InputIterator begin,InputIterator end,
OutputIterator destBegin,Predicate p) {
while (begin != end) {
if (p(*begin)) *destBegin++ = *begin;
++begin;
}
return destBegin;
}