2013-02-16 8 views
6

Tworzę C++ w wersji std::map<int, int>, które wolałbym mieć klucze posortowane od najwyższej do najniższej zamiast domyślnej kolejności sortowania. Moje badania doprowadziły mnie do std::greater który wyglądał obiecująco, ale kiedy próbuje go używać Dostaję błąd kompilacji:Jak sortować klucze mapy C++ za pomocą std :: greater?

invalid type argument of unary ‘*’ (have ‘int’)

moja deklaracja jest mapa:

std::map<int, int, std::greater<int> > numMap; 

a błąd jest wyrzucenie z tego funkcja:

void Row::addNumber(int num, int pos) { 
    numMap.insert(num, pos); 
} 

odpowiedzi na podobne pytania, takie jak this zawierać nawiasów w zgłoszeniu, tj std :: większa () - ale kiedy to włączam, otrzymuję wiele błędów dotyczących funkcji zwracającej funkcję.

+0

Czy Twój problem nie został rozwiązany podczas odczytywania mapy wstecz? tylko mówię. – fonZ

+0

Czy mówisz, że nie otrzymujesz tego samego błędu, gdy używasz domyślnego komparatora 'std :: map'? Ponieważ w tym przypadku nie powinno to mieć znaczenia. –

Odpowiedz

7

Problem - wywołanie funkcji składowej std::map::insert z niepoprawnymi parametrami: podano dwie liczby całkowite; ale musi być musi byćstd::pair<int, int>. Zobacz odniesienie: std::map::insert.

opcja Preferowana

Dla wygody (tylko nie powtarzać parametry typu mapa), utwórz typedef na mapie:

typedef std::map<int, int> IntMap; 

std::map ma wpisać definicję std::pair (para reprezentacja) - std::map::value_type. Na przykład, jeśli istnieje std::map<int, int>, std::map::value_type będzie std::pair<int, int>.

pomocą konstruktora std::map::value_typeIntMap::value_type (w tym przypadku):

class Row { 
public: 
    void Row::addNumber(int num, int pos) 
    { 
     m_numMap.insert(IntMap::value_type(num, pos)); 
    } 

private: 
    typedef std::map<int, int> IntMap; 
    IntMap m_numMap; 
}; 

Alternatywy:

  1. pomocą std::make_pair() funkcji:

    #include <utility> 
    
    ... 
    
    void Row::addNumber(int num, int pos) 
    { 
        numMap.insert(std::make_pair(num, pos)); 
    } 
    
  2. bezpośrednio używać std::pair konstruktor

    void Row::addNumber(int num, int pos) 
    { 
        numMap.insert(std::pair<int, int>(num, pos)); 
    } 
    
+0

Bardzo dużo. Funkcja wstawiania nie działa tak, jak można tego oczekiwać. :( – Xymostech

+0

Ach, dzięki, założyłem, że wstawka mapująca C++ działa tak samo, jak Java map.put - najwyraźniej powinienem zbadać to jeszcze :-( – Exupery

+1

@Euplikacja, nawiasem mówiąc, jeśli używasz klasy 'HashMap' w Javie , możesz chcieć użyć klasy 'std :: unordered_map' (dostępnej od ** C++ 11 **) - kontenera hash-map –

5

Nieco bardziej pedantyczny niż odpowiedź Sergey (która również zdecydowanie działa), zamiast użycia:

typedef std::map<int, int, std::greater<int> > MyMap; 
MyMap numMap; 

void Row::addNumber(int num, int pos) 
{ 
    numMap.insert(MyMap::value_type(num, pos)); 
} 

Świadczenie jest, że jeśli zmienisz typ mapy, masz mniej kod, aby zmienić później. I znacznie mniej prawdopodobne, ale nadal możliwe, jeśli implementacja std::map zmieni się na value_type z std::pair na coś innego (w przyszłej wersji stl), jesteś odporny na tę zmianę.

+0

+1, tak, masz rację: 'std :: map :: value_type' jest bardzo wygodne (nie powtarzać parametrów typu' std :: map'). –

Powiązane problemy