C ++ 11 Основанный на диапазоне цикл for для std :: list - PullRequest
0 голосов
/ 29 августа 2018

Если я правильно понимаю основанный на диапазоне цикл for, который расширяется

for ( range_declaration : range_expression ) loop_statement

в

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

увеличивая таким образом указатель, и если я понимаю, что std::list внутренне реализованы как двусвязные списки, не правильно ли предположить, что что-то подобное не print 0 1 2 3, так как адреса памяти не являются последовательными (подразумевается ++__begin)?

std::list<int> myList = {0, 1};
std::list<int> otherList = {10, 11};
myList.push_back(2);
myList.push_back(3);

for(auto& i: myList)
    std::cout << i << " ";

И все же он печатает правильно. Итак, переопределяет ли std::list::iterator поведение операторов, используемых в расширении диапазона для цикла?

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

увеличивая указатель

Нет, увеличение итератора .

Итератор std::list знает, что делать & hellip; в противном случае это будет бесполезно, и вы не сможете ничего сделать со своими списками. :)

Только для смежных данных, таких как векторы, итератор может быть реализован как базовый указатель, хотя даже в этом случае вы часто обнаружите, что тип итератора является, по крайней мере, своего рода оболочкой для указателей (например, в режиме отладки Visual Studio добавляет проверку границ ).

0 голосов
/ 29 августа 2018

Да, итераторы обычно перегружаются ++, *, ->, ==, !=, а иногда + integral и -- и - integral и < и т. Д., В зависимости от "категория итератора" .

std::list::iterator является двунаправленным итератором, поэтому переопределяет первый набор операторов и только -- из второго.

Итераторы не являются указателями. С другой стороны, указатели являются итераторами, и моделью, на которой основаны итераторы.

Итераторы, которые по сути являются указателями, являются итераторами в контейнерах произвольного доступа, которые хранят свои данные непрерывно; вектор, строка, массив и initializer_list.

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

...