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