Доступ к итератору for_each из лямбды

Можно ли получить доступ к итератору std::for_each, чтобы я мог удалить текущий элемент из списка std:: list с помощью лямбды (как показано ниже)

typedef std::shared_ptr<IEvent>    EventPtr;
std::list<EventPtr> EventQueue;
EventType evt;
...

std::for_each( 
    EventQueue.begin(), EventQueue.end(),

    [&]( EventPtr pEvent )
    {
        if( pEvent->EventType() == evt.EventType() )
            EventQueue.erase( ???Iterator??? );
    }
);

Я читал об использовании [](typename T::value_type x){ delete x; } здесь на SO, но VS2010, похоже, не нравится это утверждение (подчеркивает T как источник ошибок).

2 ответа

Решение

Вы используете неправильный алгоритм. использование remove_if:

EventQueue.remove_if([&](EventPtr const& pEvent)
{
    return pEvent->EventType() == evt.EventType();
});

Алгоритмы STL не дают вам доступа к итератору, используемому для итерации. В большинстве случаев это хорошо.

(Кроме того, подумайте, действительно ли вы хотите использовать std::list; маловероятно, что это правильный контейнер для вашего случая использования. Рассматривать std::vector, с помощью которого вы бы использовали идиому erase/remove для удаления элементов, которые удовлетворяют определенному предикату.)

Нет, вместо этого используйте обычный.

for( auto it = EventQueue.begin(); it != EventQueue.end(); ++it )
{
  auto pEvent = *it;
  if( pEvent->EventType() == evt.EventType() )
      it = EventQueue.erase( it );
);

Стирание - не единственный раз, когда вам может понадобиться узнать итератор из лямбды. Чтобы сделать это в более общем смысле, я использую оператор & (неявное преобразование в итератор) следующим образом:

int main (int argc, char* argv []) {
  size_t tmp [6] = {0, 1, 2, 3, 4, 5};
  std::list<size_t> ls ((size_t*)tmp, (size_t*) &tmp [6]);
  //printing next element
  std::for_each ((const size_t*)tmp, (const size_t*) &tmp [5], [] (const size_t& s) {
    std::cout << s << "->";
    std::cout << *(&s +1) << "   ";
  });
  std::cout << std::endl;
}
Другие вопросы по тегам