Я хочу удалить векторные записи, которые удовлетворяют некоторому условию, после вызова функции для них.Меня не интересует стабильное упорядочение, поэтому я обычно перемещаю последний элемент массива, чтобы заменить тот, который я изучаю.
Вопрос: какой изобразительный способ работыэто с итераторами?
(Да, erase-remove - это стандартная идиома, если вы хотите сохранить порядок, но в моем случае это не нужно, и я думаю, что будет медленнее, благодаря этим шагам, чеммоя версия приведена здесь.)
С индексом int я бы сделал это таким образом, и этот код работает:
for ( int i = (int) apc.size() - 1; i >= 0; i-- )
if ( apc[i]->blah ) {
MyFunc( apc[i] );
apc[i] = apc.back();
apc.pop_back();
}
Я пытаюсь сделать то же самое с обратным итератором, и он взрывается в++ цикла for после того, как он вошел в блок if в первый раз.Я не могу понять, почему.Если бы я на самом деле вызывал erase () для * it, я знаю, что это сделало бы его неопределенным, но я этого не делаю.Я полагаю, что pop_back () отменяет определение rbegin ().Я должен проверить, входит ли он в блок if на первой итерации и падает ли он только в этой ситуации.
for ( auto it = apc.rbegin(); it != apc.rend(); it++ )
if ( (*it)->blah ) {
MyFunc( *it );
*it = apc.back();
apc.pop_back();
}
С прямым итератором это работает, хотя мне не нравится эффект заикания, связанный с цикломостановись, когда найдешь элементы с бла-истиной.Обратный цикл немного уродлив, но, по крайней мере, это реальный цикл, а не эта кентавроподобная полу-петля-половинная смесь:
for ( auto it = apc.begin(); it != apc.end(); )
if ( (*it)->blah ) {
MyFunc( *it );
*it = apc.back();
apc.pop_back();
} else
it++;