Пространства имён
Варианты
Действия

Range-based for loop (начиная с C++11)

Материал из cppreference.com
< cpp‎ | language

 
 
Язык С++
Общие темы
Управление программой
Операторы условного выполнения
Операторы повторения
цикл for
цикл for по интервалу (C++11)
Операторы перехода
Функции
объявление функции
объявление лямбда-функции
шаблон функции
спецификатор inline
спецификаторы исключений (устарело)
спецификатор noexcept (C++11)
Исключения
Пространства имён
объявление пространства имён
псевдонимы пространства имён
Типы
спецификатор decltype (C++11)
Спецификаторы
cv-спецификаторы
спецификаторы продолжительности хранения
спецификатор constexpr (C++11)
спецификатор auto (C++11)
спецификатор alignas (C++11)
Инициализация
Литералы
Выражения
Утилиты
Типы
typedef-объявление
объявление псевдонима типа (C++11)
атрибуты (C++11)
Приведения типов
неявные преобразования
const_cast-преобразование
static_cast-преобразование
dynamic_cast-преобразование
reinterpret_cast-преобразование
C-подобное и функциональное приведение типов
Выделение памяти
Классы
Особые свойства классовых функций
Специальные функции-члены
Шаблоны
шаблон класса
шаблон функции
специализация шаблона
упакованные параметры (C++11)
Разное
Ассемблерные вставки
 
Выполняет цикл в диапазоне.
Оригинал:
Executes a for loop over a range.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Используется как более читабельный эквивалент традиционному циклу for loop по диапазону значений, например такому, как все элементы контейнера или списка.
Оригинал:
Used as a more readable equivalent to the traditional for loop operating over a range of values, for example, from some container or list.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

Содержание

[править] Синтаксис

for ( range_declaration : range_expression) loop_statement

[править] Объяснение

Приведенный выше синтаксис производит код, похожий на следующий (__range, __begin и __end приведены только для описания):
Оригинал:
The above syntax produces code similar to the following (__range, __begin and __end are for exposition only):
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}

}

(до C++17)
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}

}

(начиная с C++17)
range_expression вычисляется для определения последовательности или диапазона итерирования. Каждый элемент последовательности разыменовывается и присваивается переменной, используя тип и название, данное в range_declaration.
Оригинал:
The range_expression is evaluated to determine the sequence or range to iterate. Each element of the sequence, in turn, is dereferenced and assigned to the variable with the type and name given in range_declaration.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

begin_expr и end_expr определены следующим образом:
Оригинал:
begin_expr and end_expr are defined as follows:
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
  • Если range_expression выражение типа array, то begin_expr - __range, а end_expr - (__range + __bound), где __bound это количество элементов в массиве
    Оригинал:
    If range_expression is an expression of array type, then begin_expr is __range and end_expr is (__range + __bound), where __bound is the number of elements in the array (if the array has unknown size or is of an incomplete type, the program is ill-formed)
    Текст был переведён автоматически используя Переводчик Google.
    Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
    ;
  • Если range_expression выражение типа class C который имеет член begin и/или end (независимо от типа такого члена или доступа к нему), то begin_expr - __range.begin()end_expr - __range.end()
    Оригинал:
    If range_expression is an expression of a class type C that has a member named begin and/or a member named end (regardless of the type or accessibility of such member), then begin_expr is __range.begin() and end_expr is __range.end()
    Текст был переведён автоматически используя Переводчик Google.
    Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
    ;
  • иначе, begin_expr - begin(__range)end_expr - end(__range), которые находятся путем ADL-поиска (argument-dependent lookup) (
    Оригинал:
    Otherwise, begin_expr is begin(__range) and end_expr is end(__range), which are found via argument-dependent lookup (non-ADL lookup is not performed)
    Текст был переведён автоматически используя Переводчик Google.
    Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
    .
Если range_expression возвращает временный объект, то его срок службы продлевается до конца цикла, как указано путем связывания с ссылкой rvalue __range.
Оригинал:
If range_expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the rvalue reference __range.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

Так же, как с традиционным циклом, break может быть использован для выхода из цикла раньше, а continue для перехода к следующей итерации цикла.
Оригинал:
Just as with a traditional loop, break statement can be used to exit the loop early and continue statement can be used to restart the loop with the next element.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

[править] Ключевые слова

for

[править] Пример

#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v = {0, 1, 2, 3, 4, 5};
 
    for (int &i : v) // access by reference (const allowed)
        std::cout << i << ' ';
 
    std::cout << '\n';
 
    for (auto i : v) // compiler uses type inference to determine the right type
        std::cout << i << ' ';
 
    std::cout << '\n';
 
    for (int i : v) // access by value as well
        std::cout << i << ' ';
 
    std::cout << '\n';
}

Вывод:

0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5