2015-02-24 3 views
0

Я пытаюсь упростить рекурсивную функцию, которая получает итератор. Где-то в функции необходимо искать элемент, соответствующий данному условию, в диапазоне, идущем от итератора до конца вектора. Таким образом, я думал, что я мог бы использовать find_if, как показано ниже:Получение итератора из элемента, переданного лямбда при использовании std :: 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

Неясно, что цель функции ф. –

+0

Избавьтесь от глобальной переменной «v» (она может быть не глобальной, но использование аналогичной), и передайте это v прямо на вашу рекурсивную функцию (тогда вы можете захватить «v» в лямбда). –

+0

Я чувствую, что это случай проблемы XY. – Julian

ответ

3

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

+0

Я думал о чем-то подобном. Я надеялся на какую-то магию C++ :) Но, я полагаю, это лучшее, что может получиться, не так ли? Интересно, лучше ли использовать обычный цикл с итераторами ... – betabandido

+0

'v.data()' вместо '& v.front()' – Yakk

0

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

Неоткомпилированная код следующим образом:

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

Работает со всеми контейнерами: вектор, список, дека и т.д.