Перемещение итератора на основе диапазона вперед из цикла

#c #arrays #loops #for-loop #vector

#c #массивы #циклы #для цикла #вектор

Вопрос:

Я выполняю итерацию по многомерному vector<vector<float> > , используя for цикл на основе диапазона. Итак, что-то вроде этого:

 for(vector<float> amp;row : myVector){

    // Do some stuff

}
  

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

 for(int i = 0, j = 0; i < rows amp;amp; j < columns;   i,   j){
   // Do some stuff
}
  

Однако использование цикла на основе диапазона настолько выгодно для алгоритма, содержащегося в цикле, что я бы предпочел сохранить его, если это возможно. Возможно ли это и, если да, то как?

Комментарии:

1. почему это так выгодно? Он не делает ничего, что вы не можете сделать с итераторами

2. циклы for на основе диапазона выводят весь диапазон. Вам понадобится либо цикл другого типа, либо адаптер диапазона.

3. Кроме того, храните свои данные в одномерном векторе, который имеет гораздо лучшую производительность кэша и будет показывать реальные ускорения.

Ответ №1:

Отсутствует некоторый контекст, поэтому я просто слепо доверяю тому, что вы пишете: вы знаете, как выполнить специальное приращение с помощью цикла на основе итератора вдоль строки:

 for(int i = 0, j = 0; i < rows amp;amp; j < columns;   i,   j){
   // Do stuff
}
  

Но также у вас есть цикл на основе диапазона:

 for(vector<float> amp;row : myVector){

    // Do some stuff
}
  

И вы не хотите меняться // Do some stuff .

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

То же // Do some stuff самое можно использовать без изменений в цикле на основе итератора:

 for(auto it = myVector.begin(); it != myVector.end();   it) {
   autoamp; row = *it;

   // Do some stuff

   // Do your special increment stuff with it
}
  

Обратите внимание, что это // Do some stuff может быть точно так же, как в приведенном выше цикле for на основе диапазона.

Для получения более подробной информации о том, как циклы for на основе диапазона могут быть записаны как циклы с итераторами, я отсылаю вас к cppreference .

Ответ №2:

Попробуйте boost::range или std::ranges . Вероятно, так будет выглядеть код с boost::range .

 auto nRows = myVector | boost::adaptors::sliced(0, rows);
for(autoamp; row : nRows)
{
    auto nVals = row | boost::adaptors::sliced(0, cols);
    for(autoamp; val : nVals)
    {
    }
}