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

Ограничивает ли std:: copy дескрипторы?

При копировании данных из одного диапазона в другой вы должны быть осторожны, если частичное перекрытие между диапазонами источника и получателя. Если начало диапазона назначения перекрывает хвост исходного диапазона, простая последовательная копия будет искажать данные. Библиотека времени выполнения C имеет memmove в дополнение к memcpy для обработки таких проблем с перекрытием.

Я предполагаю, что std::copy работает как memcpy, поскольку он не учитывает совпадения между регионами-источниками и получателями. Если вы попытаетесь переместить объекты "вниз" в std::vector с помощью std::copy, вы повредите данные. Есть ли алгоритм алгоритма STL memmove для обработки таких ситуаций? Или я должен рулон с помощью обратных итераторов?

4b9b3361

Ответ 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 по-прежнему остается в пути, особенно если вы беспокоитесь о лишних копиях.