Итак, есть способ сделать его однострочным, но я не рекомендую его:
#include <vector>
#include <functional>
void odd_recursive_stuff (std::vector<int>::const_iterator& it_cur,
std::vector<int>::const_iterator it_end){}
void process_vec (const std::vector<int> &vec) {
odd_recursive_stuff ([it=std::begin(vec)]()mutable{return std::ref(it);}(), std::end(vec));
}
Я думаю, что ваш n-й рекурсивный вызов изменяет ссылку, которая затем используетсяn-1 звонящий что-то делает.В этом случае я бы порекомендовал разделить код на две функции:
odd_recursive_stuff(IT begin, IT end){
odd_recursive_stuff_impl(begin, end);
}
odd_recursive_stuff_impl(IT& begin, IT& end){
....
}
Это предоставляет общедоступный интерфейс, который просто требует итераторов.Позже, когда вы измените алгоритм так, чтобы не требовалась ссылка, или для него также потребуется end
, вам не нужно менять все вызовы.
Первое решение можетразвернем что-то похожее на это:
void process_vec (const std::vector<int> &vec) {
using IT = std::vector<int>::const_iterator;
struct _lambda_type{
_lambda_type(const IT& it):_it(it){}
//By default lambda's () is const method, hence the mutable qualifier.
std::reference_wrapper<IT> operator()()/*Not const*/{
return std::ref(_it);
}
private:
IT _it;
};
//Previous lines...
{//The line with the call.
//Lambda is created before the call and lives until the expression is fully evaluated.
_lambda_type lambda{std::begin(vec)};
odd_recursive_stuff (lambda(), std::end(vec));
}//Here's the lambda destroyed. So the call is perfectly safe.
//The rest...
}
Лямбда operator()
возвращает ссылку на локальную переменную, но она локальна для объекта лямбда, а не для самого operator()
.Поскольку лямбда-объект доживает до конца выражения (;
), вызов безопасен.Просто отметьте, что я использовал std::ref
как быстрый способ вернуть ссылку без необходимости явно указывать тип возвращаемого значения.std::reference_wrapper<T>
тогда неявно преобразуется в T&
.
return it;
вернется по значению, и [it=std::begin(vec)]()mutable ->decltype(it)&{...};
также невозможно.->decltype(std::begin(vec))&{
работает, но многословно.Другой альтернативой является явное написание типа итератора или использование using
, но это еще хуже.