C ++ Range-адаптеры / представления и правила аннулирования итераторов - PullRequest
2 голосов
/ 30 сентября 2019

Я не нашел прямой ссылки на конкретные / недопустимые правила диапазона / диапазона / просмотра диапазона при изменении базового контейнера.

Интуиция предполагает, что это будет точно так же, какправила аннулирования указателя / итератора - которые указаны в разделе контейнера стандарта .

Текущая формулировка аннулирования контейнера выглядит следующим образом:

". ..invalidating все ссылки, указатели и итераторы, относящиеся к элементам в последовательности, а также итератор конца-в-конце. "

Что поднимает вопрос: Do allдиапазоны обязательно «относятся к элементам последовательности», или они могут обращаться к элементам через интерфейс контейнера?

Мне кажется, что большинство адаптеров диапазона уже обращаются к последовательности без прямой ссылкик элементам этой последовательности (то есть ленивые представления просто создают адаптеры итераторов).

То, что кажется важным, - этобазовый диапазон у основания пирамиды вида, так сказать.


В какой-то момент мы все узнаем, что вы не можете сделать std::vector::push_back, перебирая тот же самый вектор, потому что память может двигаться и делать недействительнойитерация. Но мы также узнаем, что вы можете использовать std::vector::operator[] доступ с push_back, при условии, что вы тщательно проверяете свои size() границы правильно.

Мне кажется, то же самоеправила будут применяться к диапазонам / адаптерам / представлениям.

Итак: возможно ли заставить некоторый эквивалент std::ranges::views​::​all (или, возможно, take_view) над контейнером произвольного доступа для использованияиндексирование массива (или некоторый эквивалент косвенного / ленивого доступа к элементу), и чтобы не использовать итерацию напрямую?


Что-то, чтобы это разрешить:

std::vector<People> people = ...;
for (auto& person : std::ranges::views::lazy_all(people)) { // or ranges::lazy_take_view(people, people.size())
  if (person.has_new_child()) {
    people.push_back(person.get_new_child());
  }
}
...