2013-06-03 30 views
13

Chcę utworzyć funkcję zwyczaj porównywania dla std :: sort(), aby uporządkować kilka par klucz-wartość std :: pairC++ funkcja zwyczaj porównać do std :: sort()

Oto moja funkcja

template <typename K, typename V> 
int comparePairs(const void* left, const void* right){ 
     if((((pair<K,V>*)left)->first) <= (((pair<K,V>*)right)->first)) 
      return 1; 
     else 
      return -1; 
    } 

Następnie wewnątrz jakiejś klasie mam wektor członka klasy pary:

vector<pair<K,V>> items; 

a niektóre metody sortowania przez ten wektor klawiszy, za pomocą std :: sort()

std::sort(items.begin(), items.end(), comparePairs<K,V>); 

Mam błędów kompilacji wewnątrz, co powiedział

"nie można przekonwertować numer parametru z 'std :: pair < _Ty1, _Ty2>' do 'const void *'"

. Co to za błąd?

+2

Dlaczego jesteś biorąc swoje parametry jako 'void *' s? dlaczego nie jako "std :: pair"? –

+5

Błąd polega na tym, że mylisz komparator z 'std :: sort' z jednym dla' qsort', który wymaga argumentów 'const void *'. Napisz poprawny komparator dla 'std :: sort', który akceptuje odniesienia do' pair ', a problem zniknie. – user4815162342

+0

Dlaczego ktoś miałby to robić, gdy pokazuje całkowity brak badań, czytania, zwracania uwagi, myślenia lub czegokolwiek innego? –

Odpowiedz

19

ma już wymagane operatory porównania, które wykonują porównania leksykograficzne przy użyciu obu elementów każdej pary. Aby tego użyć, wystarczy podać operatorów porównania dla typów dla typów K i V.

Należy również pamiętać, że std::sort wymaga porównania strict weak ordeing, a <= go nie spełnia. Będziesz potrzebować, na przykład, mniejszego niż porównanie < dla K i V. Mając to na miejscu, wszystko czego potrzebujesz to

std::vector<pair<K,V>> items; 
std::sort(items.begin(), items.end()); 

Jeśli naprawdę potrzebujesz, aby zapewnić swoją funkcję porównawczą, to trzeba coś wzdłuż linii

template <typename K, typename V> 
bool comparePairs(const std::pair<K,V>& lhs, const std::pair<K,V>& rhs) 
{ 
    return lhs.first < rhs.first; 
} 
9

Twoja funkcja porównanie nie jest jeszcze źle.

Jego argumenty powinny być typem przechowywanym w zakresie, tj. std::pair<K,V>, a nie const void*.

Powinno zwrócić wartość bool, a nie wartość dodatnią lub ujemną. Zarówno (bool)1 i , więc twoja funkcja mówi, że każdy obiekt jest uporządkowany przed każdym innym obiektem co inny obiekt, co jest oczywiście niemożliwe.

Należy modelować porównania stylu mniejszego niż operator, a nie strcmp lub memcmp.

Zobacz StrictWeakOrdering, który opisuje właściwości, które musi spełniać funkcja.

15

Zobacz tutaj: http://en.cppreference.com/w/cpp/algorithm/sort.

Mówi:

template< class RandomIt, class Compare > 
void sort(RandomIt first, RandomIt last, Compare comp); 
  • zarys - porównanie funkcji, która zwraca prawdziwą jeśli pierwszy argument jest mniej niż sekundę. Podpis funkcji porównania powinny być równoważne do następujących: bool cmp(const Type1 &a, const Type2 &b);

Również tutaj jest przykładem, jak można wykorzystać std::sort użyciu niestandardowych C++ 14 polimorficzny lambda:

std::sort(std::begin(container), std::end(container), 
      [] (const auto& lhs, const auto& rhs) { 
    return lhs.first < rhs.first; 
}); 
+0

nie powinien zostac. Najpierw lhs.pierwszy? –

+0

@racarate Ups, edytowane. Dzięki! – Snps

Powiązane problemy