2012-07-19 8 views
6

¿Hay un algoritmo similar al std::copy que acepta cuatro iteradores, que denotan dos rangos?algoritmo de copia con cuatro iteradores

Básicamente, se debe detener la copia tan pronto como se haya agotado cualquier rango:

template<typename Iter> 
void copy_range(Iter begin1, Iter end1, Iter begin2, Iter end2) 
{ 
    for (; (begin1 != end1) && (begin2 != end2); ++begin1, ++begin2) 
    { 
     *begin2 = *begin1; 
    } 
} 
+2

Acabas de hacer una. ¿De qué se trata tu pregunta? –

+0

Quizás pueda usar la función C++ 11 ['std :: copy_if'] (http://en.cppreference.com/w/cpp/algorithm/copy)? –

+0

puede ser una versión pirateada de 'partial_sort_copy'? aunque francamente no veo el punto de complicarlo ... – Nim

Respuesta

10

No hay tal cosa tristemente. Lo más cercano es std::copy_n.

Y, por supuesto, el algoritmo que acaba de escribir.

Dependiendo del tipo de iterador utilizado (al azar o no), usando esto es más eficiente (ya que sólo un cheque necesita ser hecho para cada iteración) que su algoritmo:

std::copy_n(begin1, 
      std::min(std::distance(begin1, end1), std::distance(begin2, end2)), 
      begin2); 

Otro alternativa es un iterador de salida marcada, algo en la línea de este (croquis, no código verificado):

template<class Iter> 
class CheckedOutputIter { 
public: 
    // exception used for breaking loops 
    class Sentinel { } 

    CheckedOutputIter() 
     : begin(), end() { } 

    CheckedOutputIter(Iter begin, Iter end) 
     : begin(begin), end(end) { } 

    CheckedOutputIter& operator++() { 
     // increment pas end? 
     if (begin == end) { 
      throw Sentinel(); 
     } 

     ++begin; 
     return *this; 
    } 

    CheckedOutputIter operator++(int) { 
     // increment past end? 
     if (begin == end) { 
      throw Sentinel(); 
     } 

     CheckedOutputIter tmp(*this); 

     ++begin; 

     return tmp; 
    } 

    typename iterator_traits<Iter>::value_type operator*() { 
     return *begin; 
    } 


private: 
    Iter begin, end; 
}; 

Uso: 0

try { 
    std::copy(begin1, end1, CheckedOutputIter(begin2, end2)); 
} catch(const CheckedOutputIter::Sentinel&) { } 

Esto tiene aproximadamente el mismo rendimiento que su solución, pero es más ampliamente utilizable.

Cuestiones relacionadas