2015-09-29 18 views
37

La libreria standard C++ fornisce std::equal_to. Questo oggetto funzione richiama operator== su tipo T per impostazione predefinita.Perché std :: equal_to è utile?

Qual è il vantaggio dell'utilizzo di std::equal_to? Potresti fornire un esempio in cui è utile std::equal_to?

+9

Non è possibile passare '==' a una funzione, ma è possibile passare 'std :: equal_to'. – Nawaz

+2

È un po 'storico, dato che puoi anche passare '[] (auto a, auto b) {return a == b; } ' – MSalters

+0

@MSalters: non è std :: equal_to definito dal modello per essere esattamente questo? O almeno, '[] (const T & a, const U & b) {return a == b; } '? – einpoklum

risposta

37

Da utilizzare negli algoritmi. Fornisce un funtore con operatore() su di esso e quindi può essere utilizzato genericamente.

specifico (e forzato) esempio, come ha chiesto nei commenti:

// 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<>()); 

Non sono sicuro che potrebbe averne bisogno, ma è un esempio.

+1

Sarebbe fantastico, se potessi dare un esempio di codice concreto (e menzionare, perché "operator ==" non può essere usato direttamente in alcuni casi). Sfortunatamente il link alla documentazione di riferimento che ho aggiunto al post manca ancora un esempio conciso. –

+1

@SergeyA 'std :: equal_to' è un modello di classe, o si specifica un argomento modello di tipo,' std: uguale a () ', o (in C++ 14), si utilizza la sua versione trasparente (diamante)' std :: equal_to <>() ' –

+0

@SergeyA La risposta più completa. Sono d'accordo anche con @Lightness Races in Orbit - 'equal_to' è un po 'ridondante a causa delle funzioni lambda, ma la leggibilità è molto migliore. –

19

Avere std::equal_to è molto utile perché consente di utilizzare il confronto di uguaglianza come un funtore, il che significa che può essere passato come argomento a modelli e funzioni. Questo è qualcosa che non è possibile con l'operatore di uguaglianza == poiché gli operatori semplicemente non possono essere passati come parametri.

Considerare, ad esempio, come può essere utilizzato con std::inner_product, std::find_first_of e std::unordered_map.

8

In questi giorni, non è proprio così. Prima di lambdas era utile come forma di un functor di una chiamata a ==, da utilizzare nelle chiamate standard agli algoritmi. Oggi scrivi semplicemente [](auto& x, auto& y) { return x == y; }.

+3

Preferirei ancora uguale alla notazione di cui sopra. Tempo di presa molto più breve e più veloce. – SergeyA

+1

@SergeyA Più corto, sì. Più veloce da afferrare, dubbioso. – Barry

+7

@Barry, soggezionale, ovviamente.Ma lambda richiede che qualcuno legga effettivamente il lambda e si assicuri che non faccia niente di speciale. equal_to è dritto come una freccia. – SergeyA

8

È destinato principalmente a essere passato come parametro di modello a un algoritmo. Non è possibile specificare un operatore come parametro del modello, ma è possibile specificare una funzione. utilizzo tipico sarebbe qualcosa di simile:

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

Se si dispone (per esempio) una struttura di qualche tipo che contiene diversi campi, si potrebbe desiderare una funzione di confronto che confronta soltanto alcuni campi specifici che indicano l'identità, come ad come nome di una persona, ma ignorando altri campi come il peso attuale, il grado di retribuzione, ecc. In tal caso, si passa la funzione di confronto come parametro di modello e si può confrontare solo i campi che si interessano.

Per gli altri casi in cui si ha a che fare, ad esempio, cercando una matrice di numeri interi, è possibile utilizzare la funzione di confronto predefinita.

+1

non istanziate 'cmp' –

+0

in uno dei luoghi in cui ho lavorato, una delle linee guida di codifica è/era" avere sempre la costante sul lato sinistro dell'operatore == "... quindi, immagino, std :: equal_to evita anche che – basav

+0

, anche i parametri del modello di tipo predefinito per le funzioni non esistevano prima di C++ 11, e inserendo uno come ultimo parametro non consente a nessuno di specificarlo esplicitamente senza i precedenti (inibendo la deduzione di tipo) –