Я пытаюсь упростить рекурсивную функцию, которая получает итератор. Где-то в функции необходимо искать элемент, соответствующий заданному условию, в диапазоне от итератора до конца вектора. Итак, я подумал, что могу использовать find_if, как показано ниже:

typedef std::vector<Foo> FooVec;
FooVec v;

int f(FooVec::iterator it) {
  /* ... */
  auto it2 = std::find_if(it, end(v),
      [](const Foo& foo) {
        auto foo_it = /* obtain the corresponding iterator for foo. */
        return f(foo_it) == 0;
      });
  /* ... */
}

Но лямбда-функция получает элемент, а не итератор текущего элемента, поэтому я не могу легко снова вызвать f. Я мог бы искать foo в v, чтобы получить итератор, но это было бы неэффективно. В качестве альтернативы я мог бы просто использовать обычный цикл for с итераторами. Но мне было интересно, есть ли возможность использовать find_if в этой ситуации.

0
betabandido 24 Фев 2015 в 22:02

2 ответа

Лучший ответ

Беспорядочно, но v.begin() + (&foo - &v.front()) - это итератор, указывающий на foo. Обратите внимание, что это работает только потому, что vector имеет непрерывное хранилище: не пытайтесь использовать его с list или deque.

3
Steve Jessop 24 Фев 2015 в 19:06

На вашем месте я бы просто написал цикл сам. (Да, я знаю, я обычно говорю использовать алгоритмы, но это похоже на тот случай, когда сделать это самому проще).

Некомпилированный код:

for ( auto iter = it; iter != end(v); ++iter )
{
// *iter is the value; iter is the iterator
// if you have to search to the end, you can use [iter, end(v))
}

Работает со всеми контейнерами: vector, list, deque и т. Д.

0
Marshall Clow 11 Мар 2015 в 06:50