std::remove_if

【1】std::remove_if

今天突然有同事问下面这段代码应如何理解。

源码如下:

void GStiffenerBlockRepoDefaultImpl::destory(int id) noexcept
{
    m_stiffeners.erase(std::remove_if(std::begin(m_stiffeners), std::end(m_stiffeners), [&](auto s)->bool {
        return s.id == id; 
    }), std::end(m_stiffeners));
}

【2】应用示例

用代码说话,比讲解更容易理解。请看如下示例与运行结果:

(1)示例程序

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     vector<string> srcStr = { "apple", "banana", "key", "cat", "dog", "orange", "banana", "pig", "dog", "monkey" };
10 
11     auto printSrc = [&]() {
12         int index = 0;
13         for (auto& item : srcStr)
14         {
15             cout << (index++) << "|" << item << " ";
16         }
17     };
18 
19     cout << "*************************************************" << endl;
20     cout << "the original element of vector size :: " << srcStr.size() << endl;
21     cout << "the original element of vector :: " << endl;
22     printSrc();
23     cout << endl << "*************************************************" << endl;
24 
25     cout << endl << "+++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
26     auto find_str = "banana";
27     auto sd = remove_if(srcStr.begin(), srcStr.end(), [&](string element) { return element == find_str; });
28     cout << "after remove banana size :: " << srcStr.size() << endl;
29     cout << "after remove banana :: " << endl;
30     printSrc();
31 
32     int index = 0;
33     vector<string>::iterator iter = sd;
34     cout << endl << "before erase banana, prepare to erase data :: " << endl;
35     for (; iter != srcStr.end(); ++iter)
36     {
37         cout << (index++) << "|" << *iter << " ";
38     }
39 
40     srcStr.erase(sd, srcStr.end());
41     cout << endl << "after erase banana size :: " << srcStr.size() << endl;
42     cout << "after erase banana data :: " << endl;
43     printSrc();
44     cout << endl << "+++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
45 
46     cout << endl << "=================================================" << endl;
47     find_str = "dog";
48     srcStr.erase(remove_if(srcStr.begin(), srcStr.end(),
49         [&](string element) { return element == find_str; }),
50         srcStr.end());
51     
52     cout << "after erase dog size :: " << srcStr.size() << endl;
53     cout << "after erase dog data :: " << endl;
54     printSrc();
55     cout << endl << "=================================================" << endl;
56 
57     return 0;
58 }

(2)运行结果

【3】总结

(1)remove_if属于算法

STL提供六大组件:容器(containers)、算法(algorithms)、迭代器(iterators)、仿函数(functors)、配接器(adapters)、配置器(allocators)。

remove_if 隶属于算法。在头文件algorithm中,故要使用此函数,需添加

#include <algorithm>

remove_if的函数原型如下:

 1 template<class ForwardIt, class UnaryPredicate>
 2 ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
 3 {
 4     first = std::find_if(first, last, p);
 5     if (first != last)
 6         for(ForwardIt i = first; ++i != last; )
 7             if (!p(*i))
 8                 *first++ = std::move(*i);
 9     return first;
10 }

(2)remove_if 与 erase成对使用

因为remove_if函数的参数是起始、终止迭代器和判断移除的回调函数,已知通过迭代器无法得到容器本身,因而此函数无法真正删除元素。

remove_if只能把要删除的元素移到容器末尾并返回要被删除元素的首个迭代器,真正删除容器内的元素必须通过容器的成员函数erase来进行。

因此一般remove_if和erase函数是成对出现的。如上应用示例。

 

good good study, day day up.

顺序 选择 循环 总结

posted @ 2020-12-03 21:13  kaizenly  阅读(385)  评论(0编辑  收藏  举报
打赏