2013-08-17 6 views
12

Poniższy program jest skompilowany z VC++ 2012.Dlaczego std :: sort crash, jeśli funkcja porównania nie jest operatorem <?

#include <algorithm> 

struct A 
{ 
    A() 
     : a() 
    {} 

    bool operator <(const A& other) const 
    { 
     return a <= other.a; 
    } 

    int a; 
}; 

int main() 
{ 
    A coll[8]; 
    std::sort(&coll[0], &coll[8]); // Crash!!! 
} 

Jeśli zmienię return a <= other.a; do return a < other.a; następnie program działa zgodnie z oczekiwaniami, bez wyjątku.

Dlaczego?

+6

Komparator dla 'std :: sort' wymaga ścisłe słabe porządkowanie, które '<=' nie * nie * dostarcza. – WhozCraig

+0

Powinieneś napisać a (0) dla A ctor ... ale to się tutaj nie psuje! – lpapp

+0

@WhozCraig: Domyślny konstruktor inicjuje je do zera. – GManNickG

Odpowiedz

20

std::sort wymaga sorter, który spełnia ścisłego słaby nakazujący reguły, co wynika here

Więc twój comparer mówi, że a < b gdy a == b który nie zastosuje się do ścisłego słaby zamawiania zasady, jest możliwe, że algorytm się zawiesi, ponieważ wejdzie w nieskończoną pętlę.

+4

+1 Określa wymagania dla komparatora 'std :: sort's. Chciałbym to zrobić za pomocą 'std :: sort (std :: begin (coll), std :: end (coll));' jeśli Twój kompilator jest zgodny z C++ 11 (i OPs * jest * zgodny, VS2012). Jeśli kiedykolwiek zmienisz wymiary swojej tablicy lub użyjesz dowolnego ze standardowych kontenerów, będziesz zadowolony, że to zrobiłeś. – WhozCraig

+0

Wprowadzenie nieskończonej pętli powinno spowodować jej zablokowanie. Zamiast tego zrzuca rdzeń. Czemu? – btilly

+1

@ Btilly Myślę, że ponieważ 'std :: sort' używa algorytmu rekursywnego, który spowoduje przepełnienie stosu w przypadku nieskończonej pętli. – xorguy

8

Odpowiedź dla xorguy jest całkiem niezła.

Chciałbym tylko dodać jakiś cytat z normą:

25,4 Sortowanie i związanych z tym działań [alg.sorting]

Dla algorytmów innych niż opisane w 25.4.3 pracować prawidłowo, comp musi induceć ścisłe słabe zamówienie na wartości.

Określenie surowe odnosi się do zapotrzebowania na irreflexive związku (Comp + (x, x) dla wszystkich x), a termin słaby do wymagań, które nie są tak silne jak w przypadku całkowitej zamawiania , ale silniejszy niż w przypadku częściowego zamówienia.

Więc xorguy wyjaśnia to bardzo dobrze: Ty comp funkcja mówi, że a < b gdy a == b który nie zastosuje się do ścisłego słabą zasadę nakazującą ...

Powiązane problemy