Расширение до R Саху * ответ :
Причина, по которой вы не можете выполнить итерацию с использованием исходного цикла, заключается в том, что std::list
не предлагает оператора индекса (вам нужно будет использовать std::vector
вместо этого).
Альтернативный подход к диапазону, основанный на цикле (который я предпочел бы, хотя, если у вас нет особых причин для этого) & ndash; или путь, если у вас нет C ++ 11 в наличии & ndash; использует итераторы:
for(std::list<File>::iterator i = files.begin(); i != files.end; ++i)
{
std::cout << i->getFileName();
}
С C ++ 11 вы можете иметь for(auto i = files.begin(); ...
.
Варианты использования для использования цикла итератора даже в C ++ 11 могут сравнивать элементы с их наследниками:
// check for empty list first, as std::prev would fail on!)
for(auto i = files.begin(); i != std::prev(files.end()); ++i)
{
if(someCondition(*i, *std::next(i))
{
// do something else
}
}
Уже есть std::remove_if
для, и вы должны предпочесть его (вместе с лямбдой; но не забудьте применить erase
впоследствии, см. стереть -remove-идиома !), так что просто для иллюстрации; начиная с более простого подхода:
for(auto i = files.begin(); i != files.end(); ) // no ++i (!)
{
if(condition)
{
i = files.erase(i);
// fine for std::list; with std::vector, if removing more
// than one single element, we'd move or even copy subsequent
// elements multiple times, which is quite inefficient
}
}
Улучшенный вариант (это то же самое, что делает std::remove_if
):
auto pos = files.begin();
for(auto i = files.begin(); i != files.end(); ++i)
{
if(!condition)
// ^ (!)
{
*pos++ = std::move(*i);
}
}
// here, std::remove_if already stops, but returns pos...
files.erase(pos, files.end());
Минимальная проблема может остаться с операторами перемещения или копирования, которые не обрабатывают самоопределение правильно, что будет покрыто if(!condition && i != pos)
.