Страницы

Поиск по вопросам

пятница, 29 марта 2019 г.

Что значит for(int x : vector)

Недавно изучаю c++ по книге Страуструпа , и дошел до векторов, здесь в пример приведён код для прохода по всем элементам вектора
vector v = { 5,7,9,4,6,8 }; for (int x : v) cout << x << endl;
но мне не понятно что делает вот это условие:for(int x : v)


Ответ

Range-based for-loop появился в языке начиная с С++11.
По определению, в данном конкретном случае (для v типа std::vector) запись
for (int x : v) // тело цикла
эквивалентна
auto b = v.begin(); auto e = v.end(); for (; b != e; ++b) { int x = *b; // тело цикла }

В общем случае цикл вида
for ( decl-x : v ) // тело цикла
(где decl-x - это объявление), интерпретируется как
{ auto b = /* начало v */; auto e = /* конец v */; for (; b != e; ++b) { decl-x = *b; // тело цикла } }
А "начало v" и "конец v" определяются в зависимости от типа v
Для массива v это просто v и v + size Для объекта класс-типа v с хотя бы одним из членов с членами begin и end (оба должны присутствовать) это v.begin() и v.end() Для всего остального это begin(v) и end(v), где begin и end ищутся только в ассоциированных с v пространствах имен

Некоторыми следствиями такой спецификации являются:
Конец итерируемого диапазона запоминается до начала цикла, т.е. попытки расширения/сужения/переаллокации диапазона в процессе работы цикла не повлияют на запомненное значение и, в общем случае, ни к чему хорошему не приведут. Невозможно преопределить поведение для встроенных массивов путем перегрузки функций begin и end - эти функции будут просто проигнорированы. По аналогичной причине невозможно "снаружи" преопределить поведение для классов, у которых уже есть свои внутренние begin и end Для типов, с которыми используются внешние begin и end, эти begin и end должны быть объявлены непосредственно в ассоциированных пространствах имен. Объявленные в охватывающих пространствах имен begin и end найдены не будут
namespace N { struct S {}; }
int *begin(N::S &s) { return 0; } int *end(N::S &s) { return 0; }
int main() { N::S s; for (int x : s) // Ошибка - нет `begin` и `end` {} }

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

Отправить комментарий