2016-04-10 7 views
7

Warum std nicht :: sort in meine operator< Implementierung verwenden this codeWarum std nicht :: sort mein Operator <Implementierung

#include <iostream> 
#include <vector> 
#include <tuple> 
#include <algorithm> 
using namespace std; 

bool operator<(
    const tuple<int, int>& t1, 
    const tuple<int, int>& t2 
) { 
    return get<1>(t1) > get<1>(t2);// `>` so that it gets sorted in reverse 
} 

int main() { 
    vector<tuple<int, int>> v; 
    for (int i = 0; i < 10; ++i) { 
     v.push_back(make_tuple(0, i)); 
    } 
    cout << "before sort: "; 
    for (auto& x : v) { cout << get<1>(x) << ", "; } 
    cout << endl; 

    auto v2 = v; 
    sort(v2.begin(), v2.end()); 
    cout << "after sort(begin, end): "; 
    for (auto& x : v2) { cout << get<1>(x) << ", "; } 
    cout << endl; 

    sort(v.begin(), v.end(), [](auto& t1, auto& t2) { 
     return get<1>(t1) > get<1>(t2);// `>` so that it gets sorted in reverse 
    }); 
    cout << "after sort(begin, end, comparator): "; 
    for (auto& x : v) { cout << get<1>(x) << ", "; } 
    cout << endl; 

    return 0; 
} 

Die Ausgabe lautet:

before sort: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
after sort(begin, end): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
after sort(begin, end, comparator): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 

Der Ausgang Ich erwartete ist:

before sort: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
after sort(begin, end): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 
after sort(begin, end, comparator): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 
+2

Wenn Sie dieses http://ideone.com/0h1rYa sehen, funktioniert es, nachdem Sie Ihren benutzerdefinierten 'Operator <' direkt in den Standard-Namespace verschoben haben (was das nicht als gute Idee ansieht). Wenn also 'std :: tuple ' mit 'operator <' übereinstimmt, findet es zuerst den definierten Standard (in 'namespace std') zuerst (und/oder als eine bessere Übereinstimmung). – Chad

Antwort

9

Dies hat damit zu tun, wie Name Lookup funktioniert in Funktionsvorlagen (allgemein bezeichnet als Zwei-Phasen-Lookup). std::sort ist in <algorithm> definiert, und die Suche nach < findet diese Namen im Bereich der Schablonendefinition (was Ihnen nicht gehört) und diese Namen in den zugehörigen Namespaces der abhängigen Funktionsargumente (die für std::tuple wäre namespace std, was auch deine nicht einschließt).

Da sich die fraglichen Argumente im Namespace std befinden, ist es eigentlich ein undefiniertes Verhalten, Ihre Überladung in diesen Namespace einzufügen. Ihre Optionen bestehen also darin, entweder beim Standardverhalten zu bleiben (was lexikografisch < wäre) oder Ihren eigenen benutzerdefinierten Komparator bereitzustellen (wie Sie es bei Ihrer Frage tun).

Verwandte Themen