Подтвердить что ты не робот

Я уверен, что указатели на элементы std::vector действительны после перемещения вектора?

Учитывая этот пример:

std::vector<int> v1 = { 1, 2, 3 };
const int* i = &v1[1];
std::vector<int> v2(std::move(v1));
std::cout << *i << std::endl;

Несмотря на то, что во многих реализациях STL это, вероятно, будет работать, я гарантирован стандартом, что переадресация не выполняется при перемещении std::vector, а внутренняя поддержка буфера v2 такая же, как раньше от v1? Я не смог найти эту информацию ни в Интернете, ни в самом стандарте.

4b9b3361

Ответ 1

Это открытая проблема LWG 2321 [акцент мой]

Для сохранения итераторов требуется (обычно) перемещение контейнеров

[...]

[автор: Стефан Т. Лававей]
23.2.1 [container.requirements.general]/10 говорит, что если не указано иное, функция" no swap() делает недействительными любые ссылки, указатели, или итераторы, ссылающиеся на элементы контейнеров, являющиеся местами. [Примечание: Итератор end() не ссылается ни на какой элемент, поэтому он может быть признан недействительным. - end note] ". Однако переместите конструкторы и Операторы присваивания переадресации не получают аналогичной аннулирования гарантии. Гарантии требуют нескольких исключений, поэтому я не считают, что такой язык, как /11" Если не указано иное (либо явно, либо путем определения функции в терминах других функции), вызывая функцию-член контейнера или передавая контейнер как аргумент функции библиотеки не должен аннулировать итераторы или изменение значений объектов в этом контейнере. " применимо.

[2014-02-13 Issaquah]

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

STL для предоставления обновленной формулировки. Переместить в Open.

Предлагаемое разрешение:

[...]

никакой конструктор перемещения [...] контейнера (кроме array) делает недействительными любые ссылки, указатели или итераторы, ссылающиеся на элементы исходного контейнера. [Примечание: Итератор end() не ссылается ни на какой элемент, поэтому он может быть недействительным. - конечная нота]

Итак, это открытая проблема с общим согласием на ее основное решение (указатель не может быть аннулирован путем перемещения). Однако это официально не принято (пока?) Как дефект. Насколько я знаю, все основные реализации не делают недействительными указатели при построении перемещения, и это, как представляется, обычно (неявно) предоставленная гарантия.

Ответ 2

cppreference.com утверждает, что:

... есть опция, но не требуется, чтобы перемещать любые ресурсы, удерживаемые аргумент...

Похоже, что std::move просто подсказывает библиотеке, что оптимизация путем передачи права собственности возможна, но это зависит от библиотеки, нужно ли делать эту оптимизацию или нет.

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