从 lambda 访问for_each迭代器

Accessing for_each iterator from lambda

本文关键字:each 迭代器 for lambda 访问      更新时间:2023-10-16

是否可以访问 std::for_each 迭代器,所以我可以使用 lambda 从 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??? );
    }
);

我已经读到过关于在SO上使用[](typename T::value_type x){ delete x; }的信息,但是VS2010似乎不喜欢这种说法(将T下划线为错误源)。

您使用了错误的算法。 使用remove_if

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

STL 算法不允许您访问用于迭代的迭代器。 这在大多数情况下是一件好事。

(此外,考虑你是否真的想使用std::list;它不太可能是适合你的用例的容器。 考虑 std::vector ,您可以使用擦除/删除习惯用法来删除满足特定谓词的元素。

不,改用常规 。

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

并不是唯一需要从lambda了解迭代器的时间。为了以更一般的方式做到这一点,我正在使用 & 运算符(隐式转换为迭代器),如下所示:

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;
}