Я пытаюсь упростить рекурсивную функцию, которая получает итератор. Где-то в функции необходимо искать элемент, соответствующий заданному условию, в диапазоне от итератора до конца вектора. Итак, я подумал, что могу использовать 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
в этой ситуации.
2 ответа
Беспорядочно, но v.begin() + (&foo - &v.front())
- это итератор, указывающий на foo
. Обратите внимание, что это работает только потому, что vector
имеет непрерывное хранилище: не пытайтесь использовать его с list
или deque
.
На вашем месте я бы просто написал цикл сам. (Да, я знаю, я обычно говорю использовать алгоритмы, но это похоже на тот случай, когда сделать это самому проще).
Некомпилированный код:
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 и т. Д.
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .