2009-12-23 18 views
20

Al copiar datos de un rango a otro, debe tener cuidado si existe una superposición parcial entre los rangos de origen y destino. Si el comienzo del rango de destino se superpone con la cola del rango de origen, una copia secuencial simple desdibujará los datos. La biblioteca de tiempo de ejecución de C tiene memmove además de memcpy para manejar dichos problemas de solapamiento.¿std :: copy maneja rangos superpuestos?

Supongo que std::copy funciona igual que memcpy, ya que no tiene en cuenta la superposición entre las regiones de origen y de destino. Si intenta desplazar objetos "hacia abajo" en un std::vector con std::copy, va a dañar los datos. ¿Hay un algoritmo AWL analógico de memmove para manejar situaciones como esta? ¿O debería lanzar los míos con los iteradores inversos?

Respuesta

17

No maneja intervalos que se solapan si y sólo si la comenzando del rango de salida se solapa con la gama de entrada.

Afortunadamente, puede utilizar std::copy_backward lugar (que requiere que no se superpongan al final del rango de salida con el rango de entrada).

+0

'std :: copy_backward' sería útil para tratar de implementar y análogo de' memmove'. Quiero tomar la verificación de la carga de solapamiento de la persona que llama. –

9

Condiciones previas para std::copy, prohíbe una superposición:

  • Prototipo

    template <class InputIterator, class OutputIterator> 
    OutputIterator copy(InputIterator first, InputIterator last, 
            OutputIterator result); 
    
  • Condiciones previas

    • [first, last) es un rango válido.
    • resultado no es un iterador dentro del rango [first, last).
    • Hay espacio suficiente para guardar todos los elementos que se están copiando. Más formalmente, el requisito es que [result, result + (last - first)) es un rango válido de . [1]
+0

Responde la pregunta en el título. La pregunta restante es si hay un análogo de 'memmove' o si tengo que mover el mío. –

+3

Eso solo prohíbe una superposición con el inicio del rango de destino. Como dice John, se permite una superposición con el medio o el extremo, y 'std :: copy_backward' permite una superposición con el inicio (pero no el final). –

0

Parece la manera más directa sería la creación de un vector temporal del rango que desea copiar:

std::vector copiedRange(srcVecIterBegin, srcVecIterEnd); 
std::copy(copiedRange.begin(), copiedRange.end(), srcVecIterCopyLocIter); 

se puede envolver esto en una función de plantilla que debe ser hábilmente hacer un solapado usando cualquier tipo de contenedor/iterador.

+2

Sí, pero eso podría llevar a copiar mucho más de lo necesario. Preferiría corregir una función que pruebe la superposición y luego use la técnica de copia correcta para hacerlo en su lugar. –

Cuestiones relacionadas