2015-09-29 14 views
37

Die C++ - Standardbibliothek bietet std::equal_to. Dieses Funktionsobjekt ruft standardmäßig operator== vom Typ T auf.Warum ist std :: equal_to nützlich?

Was ist der Vorteil der Verwendung von std::equal_to? Können Sie ein Beispiel angeben, in dem std::equal_to nützlich ist?

+9

Sie können '==' nicht an eine Funktion übergeben, aber Sie können 'std :: equal_to' übergeben. – Nawaz

+2

Es ist ein wenig historisch, da Sie auch '[] (auto a, auto b) {return a == b; } ' – MSalters

+0

@MSalters: Ist nicht std :: equal_to Template-definiert, um genau das zu sein? Oder zumindest, '[] (const T & a, const U & b) {zurück a == b; } '? – einpoklum

Antwort

37

In Algorithmen verwendet werden. Es stellt einen Funktor mit operator() dar und kann somit generisch verwendet werden.

Spezifische (und gekünstelt) Beispiel, wie in den Kommentaren gefragt:

// compare two sequences and produce a third one 
// having true for positions where both sequences 
// have equal elements 
std::transform(seq1.begin(), seq1.end(), seq2.begin(), std::inserter(resul), std::equal_to<>()); 

Nicht sicher, die es brauchen könnten, aber es ist ein Beispiel.

+1

Es wäre großartig, wenn Sie ein konkretes Codebeispiel geben könnten (und erwähnen, warum 'operator ==' in einigen Fällen nicht direkt verwendet werden kann). Leider fehlt der Referenzdokument-Link, den ich dem Beitrag hinzugefügt habe, noch ein prägnantes Beispiel. –

+1

@SergeyA 'std :: equal_to' ist eine Klassenvorlage. Sie geben entweder ein type template Argument an,' std :: equal_to () ', oder (in C++ 14) verwenden Sie die transparente (diamond) Version' std :: equal_to <>() ' –

+0

@SergeyA Die vollständigste Antwort. Ich stimme auch @Lightness Races im Orbit zu - 'equal_to' ist wegen der Lambda-Funktionen ein wenig überflüssig, aber die Lesbarkeit ist viel besser. –

19

Die std::equal_to ist sehr nützlich, da der Gleichheitsvergleich als Funktor verwendet werden kann, was bedeutet, dass er als Argument an Vorlagen und Funktionen übergeben werden kann. Dies ist mit dem Gleichheitsoperator == nicht möglich, da Operatoren einfach nicht als Parameter übergeben werden können.

Betrachten Sie zum Beispiel, wie es mit std::inner_product, std::find_first_of und std::unordered_map verwendet werden kann.

8

In diesen Tagen ist es nicht wirklich. Vor lambdas war es nützlich als eine Funktorform eines Anrufs zu ==, für die Verwendung in Standardalgorithmusaufrufen. Heutzutage würden Sie einfach [](auto& x, auto& y) { return x == y; } schreiben.

+3

Ich würde immer noch gleich zu der obigen Notation vorziehen. Viel kürzere, schnellere Greifzeit. – SergeyA

+1

@SergeyA Kürzere, ja. Schneller zu fassen, zweifelhaft. – Barry

+7

@Barry, subjektiv, natürlich.Aber Lambda verlangt, dass jemand das Lambda tatsächlich liest und sicherstellt, dass es nichts Besonderes macht. equal_to ist gerade wie ein Pfeil. – SergeyA

8

Es soll in erster Linie als Vorlagenparameter an einen Algorithmus übergeben werden. Sie können keinen Operator als Vorlageparameter angeben, Sie können jedoch eine Funktion angeben. Typische Anwendung wäre so etwas wie:

template <class compare = std::equal_to<>, class T, class InIter> 
bool contains(InIter begin, InIter end, T value, compare cmp={}) { 
    for (InIter p = begin; p != end; ++p) 
    if (cmp(*p, value)) 
     return true; 
    return false; 
} 

Wenn Sie (zum Beispiel) eine Struktur von einer Art, die mehrere Felder enthält, könnten Sie eine Vergleichsfunktion mögen, die nur ein paar bestimmten Felder vergleichen, die die Identität angeben, wie als den Namen einer Person, aber ignorieren andere Felder wie ihr aktuelles Gewicht, Gehalt, usw. In solch einem Fall würden Sie diese Vergleichsfunktion als Vorlageparameter übergeben und in der Lage sein, nur die Felder zu vergleichen, die Ihnen wichtig sind.

In anderen Fällen, in denen Sie beispielsweise mit einem Array von Ganzzahlen suchen, können Sie die Standardvergleichsfunktion verwenden.

+1

Sie instanziieren 'cmp' –

+0

an einem der Orte, die ich gearbeitet habe, eine der Kodierungsrichtlinien ist/war" immer die Konstante auf der linken Seite des Operators == "... so denke ich, std :: equal_to vermeidet auch, dass – basav

+0

auch, Standardtyp Vorlage Parameter für Funktionen gab es nicht vor C++ 11, und die Eins als letzter Parameter wird nicht zulassen, dass jemand explizit es ohne die vorherigen angeben (hemmen Typ Abzug) –