2012-07-19 15 views
6

Esiste un algoritmo di tipo std::copy che accetta quattro iteratori, indicando due intervalli?Algoritmo di copia con quattro iteratori

In sostanza, si dovrebbe interrompere la copia non appena sia gamma è esaurito:

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

Hai appena fatto uno. Qual è la tua domanda? –

+0

Forse potresti usare la funzione C++ 11 ['std :: copy_if'] (http://en.cppreference.com/w/cpp/algorithm/copy)? –

+0

potrebbe essere una versione compromessa di 'partial_sort_copy'? anche se francamente non vedo il motivo di complicarlo ... – Nim

risposta

10

No, non c'è nulla di simile, purtroppo. La cosa più vicina è std::copy_n.

E naturalmente l'algoritmo che hai appena scritto.

seconda del tipo di iteratore utilizzato (casuale o meno), utilizzando sia più efficace (perché solo un controllo deve essere fatta per ogni iterazione) che l'algoritmo:

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

Un'altra un'alternativa è un iteratore di uscita selezionato, qualcosa sulla falsariga di questo (schizzo, non controllato codice):

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; 
}; 

utilizzati:

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

Ha all'incirca le stesse prestazioni della soluzione, ma è più ampiamente utilizzabile.