2015-09-16 18 views
5

Ho sovraccaricato l'operazione inferiore a pair<int,int>, in modo da poter ordinare un vettore in un modo particolare. Voglio che sia in ordine crescente secondo la prima chiave di una coppia, e se le prime chiavi sono uguali, allora lo farei in ordine decrescente in base alla seconda chiave.operatore sovraccarico <su coppia non utilizzata in ordinamento

Il problema è che la funzione di ordinamento non sembra essere utilizzando il sovraccarico < operatore, ma se < è chiamato a 2 coppie, l'output restituito è quello che mi aspetto. Ho allegato un frammento di codice di sotto del quale sto utilizzando per il test:

#include <iostream> 
#include <vector> 
#include <algorithm> 

using namespace std; 
bool operator<(pair<int, int> &a, pair<int, int> &b) 
{ 
    if (a.first < b.first) return true; 
    else if ((a.first == b.first) && (a.second > b.second)) return true; 
    return false; 
} 

int main() { 
    vector<pair<int, int>> test {make_pair(1,10), make_pair(3,4), make_pair(3,8), make_pair(6, 23), make_pair(1,6)}; 
    sort(test.begin(), test.end()); 
    for (int i = 0; i < test.size(); i++) 
     cout << test[i].first << " - " << test[i].second << " "; 
    cout << endl; 
    auto a = make_pair(3,4); 
    auto b = make_pair(3,8); 
    cout << (a < b) << endl; 
    return 0; 
} 

Il vettore di ingresso è {(1,10), (3,4), (3,8), (6,23), (1,6)}.

Mi aspetto che l'uscita sia {(1,10), (1,6), (3,8), (3,4), (6,23)}.

L'output ottenuto è {(1,6), (1,10), (3,4), (3,8), (6, 23)}.

Come si può vedere, l'output ottenuto è quello che si ottiene utilizzando l'operatore standard < senza sovraccaricare. Quindi ho pensato che questo potrebbe essere un problema e ho controllato (3,4) < (3,8). In questo caso, la risposta è stata restituita come falsa, in base al mio operatore sovraccarico. Quindi dove sto andando male? Perché l'operatore sovraccarico non subisce l'effetto di sort? Ci sono varie domande su SO su problemi simili, ma non è stato possibile trovare alcun aiuto.

+0

@LightnessRacesinOrbit: Sì, l'ho fatto. Cosa ti sembra sbagliato? – therainmaker

risposta

11

C'è già un operator< definito per coppie nello spazio dei nomi std, ed è quello che viene trovato dalla versione di std::sort che si sta utilizzando. Il sovraccarico non viene mai trovato. Utilizzare un predicato denominato invece:

struct MyPairComparator 
{ 
    bool operator()(const std::pair<int, int> & a, 
        const std::pair<int, int> & b) const 
    { 
     // ... 
    } 
}; 

sort(test.begin(), test.end(), MyPairComparator()); // ADL, maybe 
//        ^^^^^^^^^^^^^^^^^^ 

Inoltre, il predicato dovrebbe essere richiamabile con costanti valori, in modo da prendere gli argomenti per valore o per riferimento const.

Nota che sort è nello spazio dei nomi std. Al contrario, quando si utilizza l'espressione < in main, viene rilevato il proprio sovraccarico nello spazio dei nomi globale.

+0

Allora perché l'operatore sovraccarico lavora nell'ultima parte del codice quando chiamo 'a therainmaker

+3

@therainmaker: aggiornato. 'std :: less' è un predicato denominato nella libreria standard che (di solito) usa' <', ma potrebbe essere specializzato per i tipi di utente. I contenitori di ordinazione lo usano come comparatore di default, ma gli algoritmi di solito hanno sovraccarichi separati per la versione del predicato (sebbene, come sottolineato da @TC, il modulo non predicativo possa delegare al modulo del predicato usando ['std :: less ' a partire da C++ 14] (http://stackoverflow.com/questions/20317413/what-are-transparent-comparators)). –

1

Sembra che si usi un compilatore C++ 11, corretto e facilitato l'uso delle funzioni lambda. Qualcosa come

sort(test.begin(), test.end(), [](const pair<int, int> & a, const pair<int, int> & b) { 
    if (a.first < b.first) return true; 
    else if ((a.first == b.first) && (a.second > b.second)) return true; 
    return false; 
}); 
+2

Non penso che questo sia un miglioramento, in particolare se vuole riutilizzare quel predicato. Ma forse sono solo io. – TartanLlama

+10

"Sembra che tu usi un compilatore C++ 11" ... e poi vai avanti e usa una funzione C++ 14. –

+0

@ T.C. Scusa colpa mia. Grazie per segnalarlo. Corretto. – Shreevardhan