2012-07-19 11 views
6

Gibt es einen std::copy ähnlichen Algorithmus, der vier Iteratoren akzeptiert, die zwei Bereiche bezeichnen?kopierartiger Algorithmus mit vier Iteratoren

Grundsätzlich sollte es so bald Kopieren stoppen, da entweder Bereich erschöpft ist:

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

Sie haben gerade eins gemacht. Was ist deine Frage? –

+0

Vielleicht können Sie die Funktion C++ 11 ['std :: copy_if'] (http://en.cppreference.com/w/cpp/algorithm/copy) verwenden? –

+0

kann eine gehackte Version von 'partial_sort_copy' sein? obwohl ich ehrlich gesagt nicht den Punkt sehe, es zu komplizieren ... – Nim

Antwort

10

Nein ist es nicht traurig so etwas. Die nächste Sache ist std::copy_n.

Und natürlich der Algorithmus, den Sie gerade geschrieben haben.

Je nach Art von Iterator verwendet (zufällig oder nicht), indem diese effizienter ist (weil nur eine Prüfung muss für jede Iteration gemacht werden) als Ihr Algorithmus:

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

Another Alternative ist eine gesichtete Output-Iterator, etwas entlang der Linien von dieser (grobe Skizze, nicht geprüft code):

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

Verbrauch:

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

Dies hat ungefähr die gleiche Leistung wie Ihre Lösung, aber es ist breiter einsetzbar.