2015-01-06 11 views
8
Vergleich verwenden

Von http://www.cplusplus.com/reference/map/map/operators/ Ich bemerkte:Warum std :: map überladener Operator <nicht die

„Beachten Sie, dass keine dieser Operationen berücksichtigt das interne Vergleichsobjekt entweder Behälter, aber die Elemente vergleichen (vom Typ value_type) direkt. "

das ist zu sagen, dass der überladene Operator "<" unterstützt die Compare in seiner Erklärung nicht mit (siehe http://www.cplusplus.com/reference/map/map/)

std::map 
template < class Key,          // map::key_type 
      class T,          // map::mapped_type 
      class Compare = less<Key>,      // map::key_compare 
      class Alloc = allocator<pair<const Key,T> > // map::allocator_type 
      > class map; 

wo die Compare

vergleichen ist: Ein binäre Prädikat, das zwei Elementschlüssel als Argumente nimmt und einen bool zurückgibt. Der Ausdruck comp(a,b), wo comp ist ein Objekt dieser Art und a und b sind Schlüsselwerte, so wahr zurück, wenn a ist vor b im strengen schwach gehen als die Funktion definiert Bestellung. Das Map-Objekt verwendet diesen Ausdruck, um die Reihenfolge zu bestimmen, in der die Elemente im Container folgen, und ob zwei Elemente äquivalent sind (durch einen reflexiven Vergleich: Sie sind äquivalent wenn !comp(a,b) && !comp(b,a)). Zwei Elemente in einem Map Container können äquivalent sein Schlüssel. Dies kann ein Funktionszeiger oder ein Funktionsobjekt (siehe Konstruktor für ein Beispiel) sein. der Standardwert ist less<T>, die (a<b) das weniger-als-Operator als Anwenden derselben zurückkehrt. Aliased als Elementtyp map::key_compare.

Ich nicht ganz unter Stehen Sie, warum nicht einfach Compare in der "<" -Operator verwenden?

+0

Vielleicht war die Idee, dass '<' <'' verwenden sollte, aber ich würde sicher gerne eine weniger typische Antwort hören. – Angew

+0

(in gcc), nennen sie explizit 'lexikographic_compare', ich sehe nicht, warum sie die Vergleichsfunktion nicht einfach so propagieren, soweit ich sehen kann, es ist verfügbar ... Meine Vermutung wäre, dass die' Compare-Funktion kann beliebig komplex sein, und für diesen Fall ist es nur daran interessiert, ob das Element an der gleichen Stelle gleich ist, also könnte ein einfacheres < Nim

+0

@Nim vermutlich Wenn sie den 'Compare'-Funktor propagieren, würde das Verhalten von etwas abweichen, das im Standard spezifiziert ist. – juanchopanza

Antwort

3

Warum std::map überlastete operator < nicht den Compare

einen sehr guten Grund nicht verwendet ist, dass es nicht leicht sein würde, das Verhalten zu gewährleisten, den Sinn macht. Da der Funktor Compare statusbehaftet sein kann, können zwei Maps desselben Typs völlig unterschiedliche Sortierkriterien haben.Zum Beispiel

struct Cmp 
{ 
    Comp(bool flip) : flip(flip) {} 

    bool operator()(int lhs, int rhs) const 
    { 
    return flip ? lhs < rhs : rhs < lhs; 
    } 

    bool flip; 
}; 

Diese beiden Karten haben die gleiche Art, aber andere Ordnung:

std::map<int, std::string, Cmp> m0(Cmp(false)); 
std::map<int, std::string, Cmp> m1(Cmp(true)); 

bool b = m0 < m1; // which Cmp should this use? 

Dies ist nicht unbedingt ein Grund für < usw. verwendet, aber ein guter Grund, nicht Compare zu verwenden.

+0

Der 'flip' hier könnte ein bisschen selten sein, aber ich stimme zu, dass' <'sich beim String-Vergleich anders verhalten kann, egal ob case sensitive oder nicht ... ich denke ich verstehe es. – athos

+0

@athos Der Punkt ist, dass zwei Funktoren des gleichen Typs ein unterschiedliches Verhalten haben können. Dieses künstliche Beispiel soll das verdeutlichen. – juanchopanza

+0

Sie haben absolut Recht. Ich paraphrase es nur. – athos

4

Compare ist für den Vergleich key_type. Die < Betreiber Karte vergleicht tatsächlich mapped_typevalue_type, nicht key_type, so Compare nicht anwendbar wäre. value_type ist das Paar key_type und mapped_type.

Um ehrlich zu sein, denke ich, die Karte operator< an erster Stelle ist ein Fall von Betreiber Überlastung zu weit gegangen. Es ist nicht sofort offensichtlich, was bedeutet, eine Karte zu sagen ist "weniger als" eine andere. Wenn Sie möchten, würde ich empfehlen, es direkt aufzurufen, oder zumindest in Ihrem Code zu dokumentieren, was Ihr Kartenvergleich bedeutet.

+0

meinst du 'Compare' ist' key_type' zu ​​vergleichen, während '' '' map :: mapped_type "vergleicht? Ich verstehe dich nicht ... – athos

+1

'Compare' wird intern verwendet, um die Schlüssel einer bestimmten Karte zu sortieren (wird benutzt, damit nach Schlüsseln gesucht werden kann in O (lg n) und erlaubt auch Dinge wie' std: : lower_bound' um zu arbeiten). Der 'Operator <' der Map wird verwendet, um zwei Maps miteinander zu vergleichen. –

+0

Normalerweise würde man erwarten, dass Vergleiche nur zwischen Objekten des gleichen Typs sinnvoll sind. Zwei Karten mit verschiedenen "vergleichen" -Funktionen scheinen mir zwei verschiedene Typen zu sein. Wenn sie die gleiche "compare" -Funktion verwenden, kann es sinnvoll sein, sie als '<' -Operator zu verwenden. Aber ich weiß nicht, ob es zur Kompilierzeit möglich ist, zu entscheiden, ob die Vergleichsfunktionen gleich sind. –

Verwandte Themen