Ограничивает ли std:: copy дескрипторы?
При копировании данных из одного диапазона в другой вы должны быть осторожны, если частичное перекрытие между диапазонами источника и получателя. Если начало диапазона назначения перекрывает хвост исходного диапазона, простая последовательная копия будет искажать данные. Библиотека времени выполнения C имеет memmove
в дополнение к memcpy
для обработки таких проблем с перекрытием.
Я предполагаю, что std::copy
работает как memcpy
, поскольку он не учитывает совпадения между регионами-источниками и получателями. Если вы попытаетесь переместить объекты "вниз" в std::vector
с помощью std::copy
, вы повредите данные. Есть ли алгоритм алгоритма STL memmove
для обработки таких ситуаций? Или я должен рулон с помощью обратных итераторов?
Ответы
Ответ 1
Он не обрабатывает перекрывающиеся диапазоны, если начало выходного диапазона перекрывается с диапазоном ввода.
К счастью, вместо этого вы можете использовать std::copy_backward
(что требует, чтобы вы не перекрывали конец диапазон выхода с диапазоном ввода).
Ответ 2
Предпосылки для std::copy
запрещают перекрытие:
-
Прототип
template <class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result);
-
Предпосылки
-
[first, last)
- допустимый диапазон. - результат не является итератором в диапазоне
[first, last)
. - Существует достаточно места для хранения всех копируемых элементов. Больше формально требование состоит в том, чтобы
[result, result + (last - first))
является допустимый диапазон. [1]
Ответ 3
Кажется, самым прямым способом было бы создать временный вектор диапазона, который вы хотите скопировать:
std::vector copiedRange( srcVecIterBegin, srcVecIterEnd);
std::copy( copiedRange.begin(), copiedRange.end(), srcVecIterCopyLocIter);
Вы можете обернуть это в шаблонную функцию, которая должна умело выполнять перекрытие с использованием любого типа контейнера/итератора.
Ответ 4
std:: copy в основном используется с контейнерами, в которых вы обычно не перемещаете блоки, поэтому перекрытие не было проблемой для меня. Если вы хотите переместить блоки памяти, которые могут перекрываться, то memmove по-прежнему остается в пути, особенно если вы беспокоитесь о лишних копиях.