C++
Сравнение сборок с классическими примерами C ++, разрешенными с помощью C ++ vs C ++ 11 vs C ++ 14 vs C ++ 17
Поиск…
Прохождение через контейнер
В C ++ цикл через контейнер последовательности c
может быть выполнен с использованием индексов следующим образом:
for(size_t i = 0; i < c.size(); ++i) c[i] = 0;
В то время как простые, такие записи подвержены общим семантическим ошибкам, таким как неправильный оператор сравнения или неправильная переменная индексации:
for(size_t i = 0; i <= c.size(); ++j) c[i] = 0;
^~~~~~~~~~~~~~^
Цикл также может быть достигнут для всех контейнеров с использованием итераторов с аналогичными недостатками:
for(iterator it = c.begin(); it != c.end(); ++it) (*it) = 0;
В C ++ 11 введены диапазоны для циклов и ключевое слово auto
, что позволяет коду стать:
for(auto& x : c) x = 0;
Здесь единственными параметрами являются контейнер c
, а переменная x
- текущее значение. Это предотвращает преждевременные ошибки семантики.
Согласно стандарту C ++ 11, базовая реализация эквивалентна:
for(auto begin = c.begin(), end = c.end(); begin != end; ++begin)
{
// ...
}
В такой реализации выражение auto begin = c.begin(), end = c.end();
силы begin
и end
одинаковым типом, а end
никогда не увеличивается и не разыгрывается. Таким образом, цикл, основанный на диапазоне, работает только для контейнеров, определяемых паре iterator / iterator. Стандарт C ++ 17 смягчает это ограничение, изменяя реализацию:
auto begin = c.begin();
auto end = c.end();
for(; begin != end; ++begin)
{
// ...
}
Здесь begin
и end
допускаются к разным типам, если их можно сравнить с неравенством. Это позволяет прокручивать больше контейнеров, например, контейнер, определенный парой итератор / дозорный.