из исходного кода BeautifulSoup:
http://bazaar.launchpad.net/~leonardr/beautifulsoup/bs4/view/head:/bs4/element.py#L1260
def find_all(self, name=None, attrs={}, recursive=True, text=None,
limit=None, **kwargs):
# ...
# ...
findAll = find_all # BS3
findChildren = find_all # BS2
Лямбда повышения делает это легким.
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/if.hpp>
std::for_each( v.begin(), v.end(),
if_( MyPred() )[ std::mem_fun(&MyType::myfunc) ]
);
Вы могли даже покончить с определением MyPred (), если это просто. Это - то, где лямбда действительно сияет. Например, если MyPred имел в виду, "является делимым 2":
std::for_each( v.begin(), v.end(),
if_( _1 % 2 == 0 )[ std::mem_fun( &MyType::myfunc ) ]
);
<час> Обновление: Выполнение этого с C++ 0x синтаксис лямбды также очень хорошо (продолжать предикат как по модулю 2):
std::for_each( v.begin(), v.end(),
[](MyType& mt ) mutable
{
if( mt % 2 == 0)
{
mt.myfunc();
}
} );
На первый взгляд это похоже на шаг назад от повышения:: синтаксис лямбды, однако, это лучше, потому что более сложная логика функтора тривиальна для реализации с C++ 0x синтаксиса... где что-либо очень сложное в повышении:: лямбда становится хитрой быстро. Бета 2 Microsoft Visual Studio 2010 года в настоящее время реализует эту функциональность.
Он в порядке для изменения вектора? Можно хотеть посмотреть на алгоритм раздела.
алгоритм Раздела
Другая опция состояла бы в том, чтобы изменить Ваш MyType::myfunc
, чтобы или проверить элемент, или взять предикат в качестве параметра и использовать его для тестирования элемента, на который это воздействует.
Поскольку, чем стоимостью в for_each_if рассматривают как возможное дополнение к повышению. Не трудно реализовать Ваше собственное.
Я записал 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;
};
std::vector<int> v, matches;
std::vector<int>::iterator i = v.begin();
MyPred my_pred;
while(true) {
i = std::find_if(i, v.end(), my_pred);
if (i == v.end())
break;
matches.push_back(*i);
}
Для записи, в то время как я видел реализацию, где вызов end()
на list
был O (n), я не видел реализаций STL, где вызов end()
на vector
был чем-либо кроме O (1) - главным образом, потому что vector
с, как гарантируют, будут иметь итераторы произвольного доступа.
, Несмотря на это, если Вы волнуетесь по поводу неэффективного end()
, можно использовать этот код:
std::vector<int> v, matches;
std::vector<int>::iterator i = v.begin(), end = v.end();
MyPred my_pred;
while(true) {
i = std::find_if(i, v.end(), my_pred);
if (i == end)
break;
matches.push_back(*i);
}
Функции Lamda - идея состоит в том, чтобы сделать что-то вроде этого
for_each(v.begin(), v.end(), [](MyType& x){ if (Check(x) DoSuff(x); })
сообщение Origial здесь .
Можно использовать Повышение. Foreach:
BOOST_FOREACH (vector<...>& x, v)
{
if (Check(x)
DoStuff(x);
}