2016-06-20 10 views
1

Ich habe in etwa den folgenden Code ein, die einzigartige Segmentindizés in uniques sammeln soll:Was ist falsch mit std :: unique_copy (oder meine Verwendung davon)?

vector<int> segments; 
    // segments vector is filled in here 
    // ... 
    sort(segments.begin(), segments.end()); 
    vector<int> uniques; 
    uniques.reserve(segments.size()); 
#ifdef USE_STD_UNIQUE_COPY 
    unique_copy(segments.begin(), segments.end(), uniques.begin()); 
#else 
    if(segments.size() > 0) 
     uniques.push_back(segments[ 0 ]); 
    for(size_t i = 1; i < segments.size(); ++i) 
    { 
     if(segments[ i ] != uniques.back()) 
      uniques.push_back(segments[ i ]); 
    } 
#endif 

Wenn USE_STD_UNIQUE_COPY definiert ist, den Code nicht; wenn es nicht definiert ist, funktioniert es wie erwartet. Das ganze Stück läuft auf mehreren Threads, und ich habe noch nicht debugged, wie genau sich die Ausgabe unterscheidet. Unabhängig davon, nach cppreference std::unique_copy (1) sollte genau das tun, was der #else Teil des Codes tut.

Also die Frage: Was ist falsch in diesem Bild? Hat std::unique_copy Einschränkung, vielleicht nicht Thread-sicher? Oder vielleicht irre ich cppreference und benutze es falsch?

+6

's/uniques.begin()/back_inserter (uniques) /' –

+2

'reserve'! =' Resize'. also ist Ihre 'unique_copy' falsch, oder Sie sollten' back_inserter' verwenden. – Jarod42

+0

Der dritte Parameter muss ein 'output_iterator' sein. – Arunmu

Antwort

3

Das Problem besteht darin, dass Sie versuchen, in einen ungültigen Zielbereich zu kopieren. Im Wesentlichen weist Ihr Aufruf zum Reservieren den Speicherplatz zu, den der Vektor benötigt, ändert jedoch nicht seine Größe. Sie können also nicht direkt auf seine Elemente kopieren. Ihr alternativer Code funktioniert, weil Aufrufe von push_back die Vektorgröße um 1 erweitern und an das Ende anhängen.

Wie bereits in den Kommentaren angegeben, gibt es eine clevere Möglichkeit, unique_copy trotzdem zu verwenden. Sie ändern es, um einen back_inserter für den Zielbereich zu verwenden.

unique_copy(segments.begin(), segments.end(), back_inserter(uniques)); 

Die back_inserter schafft eine back_insert_iterator, die, wann kopiert, ruft push_back auf den Behälter.

+0

Danke, es funktioniert jetzt. – Michael

Verwandte Themen