我有一组需要操作的元素,在集合上调用成员函数:
std::vectorv; ... // vector is populated
对于没有参数调用函数,它非常简单:
std::for_each(v.begin(), v.end(), std::mem_fun(&MyType::myfunc));
如果我希望调用的函数有一个参数,则可以执行类似的操作.
我的问题是,如果满足某些条件,我想在向量中的元素上调用一个函数. std::find_if
将迭代器返回到符合谓词条件的第一个元素.
std::vector::iterator it = std::find_if(v.begin(), v.end(), MyPred());
我希望找到符合谓词的所有元素并对它们进行操作.
我一直在研究STL算法的" find_all
"或" do_if
"等价物,或者我可以用现有的STL做这个(这样我只需要迭代一次),而不是自己滚动或只是做一个标准迭代使用for循环和比较.
Boost Lambda让这很容易.
#include#include #include std::for_each( v.begin(), v.end(), if_( MyPred() )[ std::mem_fun(&MyType::myfunc) ] );
如果它很简单,你甚至可以取消定义MyPred().这是lambda真正闪耀的地方.例如,如果MyPred意味着"可以被2整除":
std::for_each( v.begin(), v.end(), if_( _1 % 2 == 0 )[ std::mem_fun( &MyType::myfunc ) ] );
std::for_each( v.begin(), v.end(), [](MyType& mt ) mutable { if( mt % 2 == 0) { mt.myfunc(); } } );
乍一看,这看起来像是从boost :: lambda语法向后退一步,但是,它更好,因为使用c ++ 0x语法实现更复杂的functor逻辑很简单......在boost :: lambda中任何非常复杂的东西都会变得棘手很快.Microsoft Visual Studio 2010 beta 2目前实现此功能.
我写了一个for_each_if()
和一个for_each_equal()
我认为你正在寻找的东西.
for_each_if()
使用谓词仿函数来评估相等性,并for_each_equal()
获取任何类型的值并使用直接比较operator ==
.在这两种情况下,传递的函数都会在通过相等性测试的每个元素上调用.
/* --- For each 25.1.1 template< class InputIterator, class Function, class T> Function for_each_equal(InputIterator first, InputIterator last, const T& value, Function f) template< class InputIterator, class Function, class Predicate > Function for_each_if(InputIterator first, InputIterator last, Predicate pred, Function f) Requires: T is of type EqualityComparable (20.1.1) Effects: Applies f to each dereferenced iterator i in the range [first, last) where one of the following conditions hold: 1: *i == value 2: pred(*i) != false Returns: f Complexity: At most last - first applications of f --- */ template< class InputIterator, class Function, class Predicate > Function for_each_if(InputIterator first, InputIterator last, Predicate pred, Function f) { for( ; first != last; ++first) { if( pred(*first) ) f(*first); } return f; }; template< class InputIterator, class Function, class T> Function for_each_equal(InputIterator first, InputIterator last, const T& value, Function f) { for( ; first != last; ++first) { if( *first == value ) f(*first); } return f; };
改变矢量可以吗?您可能想要查看分区算法.
分区算法
另一个选择是更改您MyType::myfunc
要么检查元素,要么将谓词作为参数并使用它来测试它正在操作的元素.