2017-02-21 4 views
0

Ich verwende std::mismatch, um zu überprüfen, ob zwei Vektoren von Strukturen genau gleich sind. In meinem Programm sind sie normalerweise nicht, aber in Ausnahmefällen kann es passieren. Im documentation finde ich folgendes:Rückgabewert std :: Mismatch für gleiche Vektoren

„wenn die verglichenen Elemente in beiden Sequenzen alle aufeinander abgestimmt sind, wird die Funktion ein Paar mit dem ersten Satz kehrt in der gleichen relativen Position in dem zweiten und dem zweiten Satz zu dem Element last1 Sequenz."

Wenn ich jedoch zwei vollständig identische Vektoren erzeuge, gibt std :: mismatch keinen Wert zurück. Ein kleines Beispiel von dem, was ich zu tun versucht:

#include <vector> 
#include <algorithm> 
#include <utility> 

struct structwithnumber { 
    int id; 
}; 

bool compare_structs (structwithnumber* struct1, structwithnumber* struct2) { 
    return struct1->id == struct2->id; 
}; 

bool compare_structvectors(std::vector<structwithnumber*> v1, std::vector<structwithnumber*> v2) { 
    if (v1.size() != v2.size()) 
    { 
     return false; 
    } 
    std::pair<std::vector<structwithnumber*>::iterator, std::vector<structwithnumber*>::iterator> mypair; 
    mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs); 
    return (compare_structs(*mypair.first, *mypair.second)); 
} 

void simple_example() { 
    structwithnumber* struct1 = new structwithnumber(); 
    structwithnumber* struct2 = new structwithnumber(); 
    struct1->id = 1; 
    struct2->id = 2; 
    std::vector<structwithnumber*> v1; 
    std::vector<structwithnumber*> v2; 
    v1.push_back(struct1); 
    v1.push_back(struct2); 
    v2.push_back(struct1); 
    v2.push_back(struct2); 
    compare_structvectors(v1, v2); 
} 

Wenn ich diesen Code in Visual Studios laufen 15 Ich erhalte eine Fehlermeldung auf der Linie:

return (compare_structs(*mypair.first, *mypair.second)); 

Bei der weiteren Untersuchung stellt sich mypair bleibt aus leer nach Nichtübereinstimmung Aus der Dokumentation würde ich jedoch den letzten Wert jedes Vektors zurückgeben. Habe ich falsch verstanden, wie sich Mismatch verhalten würde, wenn zwei Sequenzen dargestellt werden, in denen alle Elemente übereinstimmen?

+2

„Ich erhalte eine Fehlermeldung“ - sollten Sie das die Art des Fehlers mit dem Publikum zu teilen? (Kopieren und Einfügen aus dem Ausgabefenster.) – molbdnilo

+1

Und [hier] (http://en.cppreference.com/w/cpp/algorithm/mismatch) ist eine zuverlässigere Referenzseite. – molbdnilo

Antwort

3

std::mismatch, für den Fall, dass alles übereinstimmt, gibt einen (t mindestens eine) Vergangenheit-am-Ende-Iterator zurück. Sie können es nicht dereferenzieren, wie Sie es in compare_structs(*mypair.first, *mypair.second) tun.

Der Code sollte für den Fall wie folgt testen:

mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs); 

if(mypair.first == v1.end()) { 
    // No mismatch, do something sensible 
} else { 
    return (compare_structs(*mypair.first, *mypair.second)); 
} 
+0

Danke. Ich werde es zu ändern: MyPair = Std :: Mismatch (v1.begin(), v1.end(), v2.begin(), compare_struct); Rückgabe (meinPaar.first == v1.end()); Als die zweite Anweisung wird immer falsch sein. – MJV

0

Wenn ich jedoch zwei Vektoren erzeugen, die völlig gleich sind, std :: Mismatch gibt keinen Wert

Natürlich tut es, es muss etwas zurückgeben.

Bei weiteren Untersuchungen stellt sich heraus, dass mein Paar nach dem Mismatch leer bleibt.

Was bedeutet das? Wie ist mein Paar leer? Es ist ein Paar, es hatte genau zwei Mitglieder, als es erstellt wurde, und es hat immer noch genau zwei Mitglieder nach dem Anruf zu mismatch. Wenn beide Sequenzen übereinstimmen, handelt es sich jedoch um ein Paar end Iteratoren. Das ist so, als wenn man sagt, dass man ein paar leere nicht übereinstimmende Sequenzen hat (was immer noch nicht dasselbe ist wie ein unmögliches leeres Paar).

Sie können diese Iteratoren nicht dereferenzieren, daher ist Ihr Code defekt. Sie müssen prüfen, bevor dereferencing:

const bool v1_mismatch = (mypair.first != v1.end()); 
const bool v2_mismatch = (mypair.second != v2.end()); 
const bool identical = !(v1_mismatch || v2_mismatch); 

if (v1_mismatch && v2_mismatch) { 
    // this is the only case where you can dereference both 
    return compare_structs(*mypair.first, *mypair.second); 
} 
// otherwise you can dereference at most one iterator, 
// and if v1,v2 are identical, you can't dereference either 
+0

du meinst wahrscheinlich '||' dort – Ap31

+0

Ja, ich war in zwei Köpfen darüber, wie viel Detail in das letzte Bit ... – Useless

Verwandte Themen