Другие языки программирования и технологии

С++ функции move и copy в библиотеке algorithm

Что означает следующее утверждение: "Значение элементов в [first,last)передается элементам, указанным в результате . После вызова элементы в диапазоне [first,last)остаются в неопределенном, но действительном состоянии."
Что означает слово выражение "неопределенное состояние"? На практике же элементы перемещаемых элементов остаются теми же... (Пробовал с различными типами данных и итераторами, также пробовал разные оптимизационные режимы, в т. ч. и без оптимизаций, также пробовал разные компиляторы, но состояние элементов сохраняется всегда) Если это действительно всегда так, то зачем вообще использовать copy?
А вы попробуйте провернуть эти операции (move и copy), например, над векторами из каких-то сложных элементов - например, других векторов. И посмотрите, что останется в векторе-источнике после move и после copy.
Читайте про move-семантику.
АФ
Александр Федотов
51 164
Лучший ответ
Кайрат Жарасбаев щас попробую... так не пробовал
Кайрат Жарасбаев Да, вы правы... вектор из векторов уже выдает ошибку при попытке вывести элементы, которые были перемещены в другой)))) теперь понятно...
Вы создали в динамической памяти контейнер данных в размере 1 гигабайт. Если будете копировать используя std::copy, то вам потребуется ещё один гигабайт и некоторое время, чтобы выделить память и переписать в неё данные. Если вам два экземпляра ни к чему, то имеет смысл только передать адрес на первый байт контейнера и привязать его к новому указателю. Это называется перемещением, выполняется с использованием std::move. После его выполнения не рекомендуется использовать предыдущий указатель. В зависимости от реализации он может потерять связь с областью памяти на которую указывал. По умному так и должно быть. Связываться таким образом могут адреса начала и конца контейнера (опять же зависит от реализации и задачи).

Если после перемещения контейнера по итераторам второго объекта изменить его размер, то итераторы первого объекта ничего об этом не узнают и в случае попытки обратиться к элементам контейнера по итераторам первого объекта возникает неопределённое поведение.
move возможно при перемещении списка
изменяет ссылки в нем на каждый следующий элемент списка,
но оставляет их валидными, т. е. фактический адрес следующего элемента
списка будет другой, но сам список останется целостным.

copy работает как-то по другому, см документацию
тут
ru.cppreference.com/w/cpp/algorithm
Изначальное расположение после move можно использовать (ничего не взорвется), но в этом нет смысла - значения будут (могут быть) не теми, что изначально. Какими - какими угодно, зависит от конкретной реализации алгоритма.
Edgar Movsisyan
Edgar Movsisyan
39 077
Кайрат Жарасбаев Да я проверил утверждение user с векторами из векторов и сразу стало все понятно)))
Если значения не передаются, то элементы имеют неопределенные значения. Я это так понял. (Но если не помог, извини)
Андрей Сухин
Андрей Сухин
16 271
Кайрат Жарасбаев Значения передаются. Грубо говоря мы перемещаем все элементы 1-ого массива во второй. Само перемещение работает как копия не меняя при этом 1 массив))) оба массива остаются на практике целыми.... вот мне и интересно стало...