Диапазон на основе цикла с & - PullRequest
0 голосов
/ 27 февраля 2019

Я не нашел вопрос, который отвечает на ту часть, в которой я запутался, и я прошу прощения, если кто-то ответил на него.

Я запутался в том, что происходит в этом цикле for, как он проходит по адресам?

int arr[] = {1,2,3,4,5};
for(const int &arrEntry : arr){
     cout << arrEntry << " ";
}

Ответы [ 3 ]

0 голосов
/ 27 февраля 2019

Цикл for в C ++, основанный на диапазоне, на самом деле является просто синтаксическим сахаром, эквивалентным следующему (предоставляется cppreference :

for (range_declaration : range_expression) loop_statement;

// is equivalent to:

{
    auto && __range = range_expression ;
    for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {

        range_declaration = *__begin;
        loop_statement

    }
}

В приведенном выше блоке кода begin_expr и end_expr эквивалентны std::begin(__range) и std::end(__range) соответственно.

Таким образом, в случае использования const int &arrEntry, arrEntry фактически объявляется внутри "реального" (нормального) для цикла итаким образом, в каждой итерации он ссылается на другой объект в диапазоне, как если бы он напрямую использовал необработанные итераторы.

Обратите внимание, что это было бы невозможно, если бы arrEntry был объявлен вне цикла for, как ссылкине может быть переназначен для ссылки на другой объект.

Еще один важный (побочный) факт, который следует учитывать, заключается в том, что range_expression сохраняется в течение всей продолжительности цикла, что означает, что вы можете использовать prvalue там (например, вызов функции, которая возвращает std::vector<int> по значению.

0 голосов
/ 27 февраля 2019

Возможно, размещение & вызывает путаницу.Помните, что C ++ не волнует, где вы ставите пробелы.Поскольку это: for (const int &arrEntry : arr) является объявлением новой переменной arrEntry для использования внутри цикла, использование & в левой части ее имени означает, что мы определяем объект, которыйимеет тип ссылки , в частности arrEntry является ссылкой на const int.Это означает, что в цикле arrEntry не является копией данных, над которыми вы зацикливаетесь, а только ссылкой на них.const означает, что вы не можете изменить его значение.

Если бы это не было объявлением, и если arrEntry были определены ранее, то выражение &arrEntry действительно будет принимать адрес arrEntry.В теле цикла arrEntry уже определено, и вы можете взять его адрес с помощью &arrEntry

int arr[] = {1,2,3,4,5};
for(const int &arrEntry : arr){
     cout << arrEntry << " "; // prints a const int
     cout << &arrEntry << " "; // prints a pointer to a const int
}
0 голосов
/ 27 февраля 2019

В вашем коде & arrEntry является ссылкой на обр.Это подразумевается в цикле For-based Ranged.

for(const int &arrEntry : arr){
     cout << arrEntry << " ";
}

Вы можете сделать это без ссылки, результат будет таким же.Но обратите внимание, что значение arr копируется в arrEntry.

for(const int arrEntry : arr){
     cout << arrEntry << " ";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...