Использование ссылок в качестве управляющей переменной в основанном на диапазоне цикле в c ++ - PullRequest
0 голосов
/ 03 сентября 2018

Я возился с основанными на диапазоне циклами, как этот:

int a[] = {1, 2, 3, 4};

for(auto i : a){
    cout << i;
}

(поправьте меня здесь, если я ошибаюсь) Я полагаю, что i присваивается в начале каждой итерации со следующим значением в контейнере последовательности a как:

i = a[0]… итерация 1

i = a[1]… итерация 2

...

i = a[9]… итерация 10

Я хотел спросить, как это работает, когда переменная управления цикла является ссылкой:

for(int &i : a){...}

Поскольку ссылка не присваивается при инициализации, а связывается, и привязка никогда не изменяется, то как i выполняет итерацию через a, сохраняя значение элемента a в данной итерации, но когда ссылка назначена, кроме в объявлении это похоже на присвоение исходной переменной. Чтобы изменить элементы массива, мы должны использовать ссылку, мой вопрос заключается в том, как можно привязать одну ссылку к различным переменным (то есть элементам a во время цикла), поскольку каждый элемент может быть изменен с помощью одной и той же переменной ссылки внутри цикла.

Спасибо

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Я нашел эту информативную статью , которая поможет вам:

Я думаю, что приведенная ниже цитата из статьи отвечает на ваш вопрос:

В цикле for на основе диапазона auto& создаст ссылки (множественное число) на исходные элементы в диапазоне.

Также рассматриваются различные способы использования auto в цикле for на основе диапазона.


for (auto x : range)

Это создаст копию каждого элемента в диапазоне. Поэтому используйте этот вариант, если вы хотите работать с копией.


for (const auto x : range)

Использование const auto может означать, что вы хотите работать с неизменяемой копией каждого элемента.


for (auto& x : range)

Используйте auto&, если вы хотите изменить элементы в диапазоне в неуниверсальном коде.


for (const auto& x : range)

Используйте const auto&, если вам нужен доступ только для чтения к элементам в диапазоне, даже в общем коде


for (auto&& x : range)

Используйте auto&&, если вы хотите изменить элементы в диапазоне в общем коде


for (const auto&& x : range)

Этот вариант будет привязан только к значениям, которые вы не сможете изменить или переместить из-за констант. Это делает его менее чем бесполезным. Следовательно, нет причин выбирать этот вариант вместо const auto&.


for (decltype(auto) x : range) // C++14

Это означает: применять автоматическое вычитание типа, но использовать decltype правила. Принимая во внимание, что auto удаляет cv квалификаторы и ссылки верхнего уровня, decltype сохраняет их.

0 голосов
/ 03 сентября 2018

Простая идея похожа на итератор STL. Можно придумать аналогичный подход к итератору для цикла, например,

for(auto it = a.begin(); it != a.end(); it++){ .... }

Теперь, для подхода, основанного на диапазоне, на каждой итерации ваша ссылка перемещается в следующую ячейку памяти, и доступ к ссылочной ячейке может изменить все, что вам нужно.

for(int& i : a) { ... } 

i ссылки на ячейку памяти 0xffffcbd0 на первой итерации.
i ссылки на ячейку памяти 0xffffcbd4 на второй итерации.

... и так далее.

Попробуйте напечатать позиции памяти i с &i.

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