考虑以下情况:
typedef struct myStruct
{
int cn;
std::string dn;
} MyStruct;
int main()
{
std::vector<MyStruct> v;
// fill some data
...
...
int c = 1;
std::vector<MyStruct>::iterator it = std::find_if(v.begin(), v.end(),
[c](const MyStruct& m) -> bool { return m.cn == c; });
// use 'it' to do stuff
}
如果v
包含MyStruct
个对象,使得成员变量cn
在多个条目中具有值c (=1)
,那么如何处理该方案?当std::find_if()
将迭代器返回到范围中的第一个元素时,剩下的就是什么呢?
答案 0 :(得分:4)
find_if
找到范围中的第一个元素并将迭代器返回给它。为了找到所有你可以写循环,它将从it
:
std::vector<MyStruct>::iterator it = v.begin();
while (it != v.end())
{
it = std::find_if(it, v.end(),
[c](const MyStruct& m) -> bool { return m.cn == c; });
if (it != v.end())
{
// process founded item
++it;
}
}
或者您可以对序列进行排序并使用equal_range算法,该算法将返回std::pair
个迭代器。
答案 1 :(得分:3)
使用当前的标准库,您必须使用谓词编写一个循环std::find_if
(如果可以使用C ++ 11/14,则编写lambda),或使用std::copy_if
复制每个匹配一个新序列。
当Ranges proposal可用时(在技术规范中与C ++ 17一起使用),事情变得更加容易,例如您将能够编写一个可组合的视图和操作链:
#include <range/v3/all.hpp>
#include <iostream>
#include <vector>
using namespace ranges;
int main()
{
auto const is_even = [](auto x) { return x % 2 == 0; };
auto const print = [&](auto x) { std::cout << x << ","; return x; };
std::vector<int> v { 1, 11, 42, 57, 63, 72 };
v | view::filter(is_even) | action::transform(print);
}
Live On Coliru (已与range-v3 library配合使用。)