for_each_erase_if ?
От: nen777w  
Дата: 28.12.11 13:55
Оценка:
Существует ли в boost или std сабжевый алгоритм для контейнеров с поддержкой операции erase() с возвратом следующего итератора?
Или нужно писать самому?
Re: for_each_erase_if ?
От: AndrewJD США  
Дата: 28.12.11 15:09
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Существует ли в boost или std сабжевый алгоритм для контейнеров с поддержкой операции erase() с возвратом следующего итератора?

N>Или нужно писать самому?

Без возврата следующего итератора можно посмотреть на remove_erase_if.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re: for_each_erase_if ?
От: Сыроежка  
Дата: 28.12.11 15:09
Оценка: -1
Здравствуйте, nen777w, Вы писали:

N>Существует ли в boost или std сабжевый алгоритм для контейнеров с поддержкой операции erase() с возвратом следующего итератора?

N>Или нужно писать самому?

Среди стандартных алгоритмов я такой не знаю. Соответствующий алгоритм должен очевидно иметь в качестве параметров два предиката: первый для проверки условия и второй для вызова функции. При этом в первый предикат должен передаваться разыменованный итератор, а во второй предикат — сам итератор. За boost не берусь отвечать.
Меня можно встретить на www.cpp.forum24.ru
Re: for_each_erase_if ?
От: Сыроежка  
Дата: 28.12.11 15:37
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Существует ли в boost или std сабжевый алгоритм для контейнеров с поддержкой операции erase() с возвратом следующего итератора?

N>Или нужно писать самому?

Я думаю, что подобный алгоритм должен выглядеть следующим образом:


template <typename ForwardIterator,
          typename Condition,
          typename Function>

void execute_if( ForwardIterator first,
                 ForwardIterator last,
                 Condition cond,
                 Function func )
{
   while ( first != last )
   {
      if ( cond( *first ) ) first = func( first );
      else ++first;
   }
}


При этом при передаче функционального объекта func придется его конструктору передавать в качестве параметра неконстатную ссылку на ваш контейнер.
Меня можно встретить на www.cpp.forum24.ru
Re[2]: for_each_erase_if ?
От: nen777w  
Дата: 28.12.11 15:55
Оценка:
С>Среди стандартных алгоритмов я такой не знаю. Соответствующий алгоритм должен очевидно иметь в качестве параметров два предиката: первый для проверки условия и второй для вызова функции. При этом в первый предикат должен передаваться разыменованный итератор, а во второй предикат — сам итератор. За boost не берусь отвечать.

Вопрос не о том как написать а о том как не писать велосипедов.
Re[2]: for_each_erase_if ?
От: nen777w  
Дата: 28.12.11 16:05
Оценка:
N>>Существует ли в boost или std сабжевый алгоритм для контейнеров с поддержкой операции erase() с возвратом следующего итератора?
N>>Или нужно писать самому?
AJD>Без возврата следующего итератора можно посмотреть на remove_erase_if.

Это который в boost/range, спасибо.
Мне как раз весь контейнер прошерстить нужно, жаль что нет более универсального основанного на итераторах, когда понадобится нужно будет самому писать.
Re: for_each_erase_if ?
От: IROV..  
Дата: 28.12.11 16:08
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Существует ли в boost или std сабжевый алгоритм для контейнеров с поддержкой операции erase() с возвратом следующего итератора?

N>Или нужно писать самому?

remove_if + erase?

или я чтото не понял
я не волшебник, я только учусь!
Re[2]: for_each_erase_if ?
От: kpcb Россия  
Дата: 28.12.11 16:09
Оценка:
Здравствуйте, Сыроежка, Вы писали:

С>
С>template <typename ForwardIterator,
С>          typename Condition,
С>          typename Function>

С>void execute_if( ForwardIterator first,
С>                 ForwardIterator last,
С>                 Condition cond,
С>                 Function func )
С>{
С>   while ( first != last )
С>   {
С>      if ( cond( *first ) ) first = func( first );
С>      else ++first;
С>   }
С>}
С>


Это, как минимум, не будет работать для удаления из вектора, т.к. после первого удаления last станет невалидным
Re[3]: for_each_erase_if ?
От: Сыроежка  
Дата: 28.12.11 16:16
Оценка:
Здравствуйте, kpcb, Вы писали:

K>Здравствуйте, Сыроежка, Вы писали:


С>>
С>>template <typename ForwardIterator,
С>>          typename Condition,
С>>          typename Function>

С>>void execute_if( ForwardIterator first,
С>>                 ForwardIterator last,
С>>                 Condition cond,
С>>                 Function func )
С>>{
С>>   while ( first != last )
С>>   {
С>>      if ( cond( *first ) ) first = func( first );
С>>      else ++first;
С>>   }
С>>}
С>>


K>Это, как минимум, не будет работать для удаления из вектора, т.к. после первого удаления last станет невалидным


Да, вы правы. Я когда писал, больше думал о структуре этого алгоритма, то есть какие должны быть у него параметры.
Меня можно встретить на www.cpp.forum24.ru
Re[3]: for_each_erase_if ?
От: Сыроежка  
Дата: 28.12.11 16:27
Оценка: -1
Здравствуйте, nen777w, Вы писали:

С>>Среди стандартных алгоритмов я такой не знаю. Соответствующий алгоритм должен очевидно иметь в качестве параметров два предиката: первый для проверки условия и второй для вызова функции. При этом в первый предикат должен передаваться разыменованный итератор, а во второй предикат — сам итератор. За boost не берусь отвечать.


N>Вопрос не о том как написать а о том как не писать велосипедов.


Можно просто попробовать решить эту задачу, как говорится, в лоб без причуд


template <typename Container,
          typename UnaryPredicate>
void execute_if( Container &c, UnaryPredicate unary_predicate )
{
   typename Container::iterator first = c.begin();

   while ( first != c.end() )
   {
      if ( unary_predicate( *first ) ) first = c.erase( first );
      else ++first;
   }
}
Меня можно встретить на www.cpp.forum24.ru
Re[4]: for_each_erase_if ?
От: Кодт Россия  
Дата: 28.12.11 19:10
Оценка:
Здравствуйте, Сыроежка, Вы писали:

С>Можно просто попробовать решить эту задачу, как говорится, в лоб без причуд


Так это и есть boost::remove_erase_if, разве нет?
Конечно, не считая того, что данная реализация работает на векторе за квадратичное время (точнее, за O(n*m) где n — длина вектора, m — количество удаляемых элементов).
Перекуём баги на фичи!
Re[5]: for_each_erase_if ?
От: Сыроежка  
Дата: 28.12.11 19:32
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Сыроежка, Вы писали:


С>>Можно просто попробовать решить эту задачу, как говорится, в лоб без причуд


К>Так это и есть boost::remove_erase_if, разве нет?

К>Конечно, не считая того, что данная реализация работает на векторе за квадратичное время (точнее, за O(n*m) где n — длина вектора, m — количество удаляемых элементов).

Для вектора естественно проще использовать комбинацию стандартного алгоритма std::remove_if и функцию — член класса erase.

Но автора темы это почему-то не устраивает.
Меня можно встретить на www.cpp.forum24.ru
Re[6]: for_each_erase_if ?
От: Кодт Россия  
Дата: 29.12.11 08:44
Оценка:
Здравствуйте, Сыроежка, Вы писали:

К>>Так это и есть boost::remove_erase_if, разве нет?

К>>Конечно, не считая того, что данная реализация работает на векторе за квадратичное время (точнее, за O(n*m) где n — длина вектора, m — количество удаляемых элементов).

С>Для вектора естественно проще использовать комбинацию стандартного алгоритма std::remove_if и функцию — член класса erase.

С>Но автора темы это почему-то не устраивает.

Сдаётся мне, что не устраивает именно из-за того, что для разных контейнеров одно и то же действие нужно выполнять разными способами.
И что буст именно так и поступает, перегружая функцию для известных типов контейнеров.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.