Я не нашел прямой ссылки на конкретные / недопустимые правила диапазона / диапазона / просмотра диапазона при изменении базового контейнера.
Интуиция предполагает, что это будет точно так же, какправила аннулирования указателя / итератора - которые указаны в разделе контейнера стандарта .
Текущая формулировка аннулирования контейнера выглядит следующим образом:
". ..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());
}
}