std::sort i wektor wskaźników do class

0

Chce aby sort posortował mi wektor klas:

class klasa {
  public:
  String name;
}

bool cmpRank(klasa* a, klasa* b) {
...
}

vector<klasa*> wektor;
std::sort(wektor.begin(), wektor.end(), cmpRank);

w tym momencie program protestuje bo jako dwa pierwsze argumenty dostaje zmienne void, jak to obejść ?

0
class cmpRank {
bool operator()(klasa *a, klasa *b) {
        ....
    }
};

ale nie zdziwiłby się, gdyby się okazało, że wystarczy dodać const zaraz po gwiazdkach.

0

ale nie zdziwiłby się, gdyby się okazało, że wystarczy dodać const zaraz po gwiazdkach.
Nie trzeba. Szablonem nie wymusisz typu.
Poza tym po co const przy obiekcie przekazywanym przez wartość ? Jak już to referencja do const wskaźnika (klasa * const &a). W tym przypadku bez const'a by nie poszło.

0

racja, ale w takim razie czemu mu nie zadziałało? Wygląda Ok!

0

Bo jest OK.

Pytanie w czym problem ?

0

Metody begin i end listy zwracają iteratory. Spróbuj z front i back, które referencje zwracają.

0
wektor napisał(a)

Metody begin i end listy zwracają iteratory. Spróbuj z front i back, które referencje zwracają.

std::sort przyjmuje jako argumenty iteratory, nie referencje. Rozwiazanie z funktorem nie ma prawa nie dzialac - wypadaloby tylko dodac dziedziczenie po std::unary_function<klasa*, klasa*, bool>

0

Jak już to std::binary_function, ale naprawdę nie ma takiej potrzeby. Te szablony są potrzebne, gdy stosujesz bindowanie, a to nie jest ten przypadek.

0

@MarekR22:
Zgadzam się z Tobą całkowicie - używam tych szablonów głównie z przyzwyczajenia :)

Jezeli chcesz zdefiniować operator porównania na poziomie klasy lepszym rozwiązaniem jest użycie boost::indirect_iterator. Pozwala on uzyskać iterator zwracający referencję mimo iż kolekcja przechowuje wskaźniki na obiekty.

W ponizszym przykladzie posortowanie wedlug pola name wymaga:

  • zdefiniowania w klasie operatora< (mozemy rowniez zdefiniowac go zewnetrznie)
  • typedefa dla boost::indirect_iteratorFooVector::iterator dla wygody
  • wywolania std::sort z adaptorami zamiast iteratorow kolekcji - std::sort(Adaptor(vec.begin()), Adaptor(vec.end()))

Przykład:

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <boost/iterator/indirect_iterator.hpp>

class Foo
{

public:
    Foo(const std::string name): _name(name) { }
    const std::string& getName() const { return _name; }

    bool operator<(const Foo& other) const { return _name < other._name; }

private:
    std::string _name;

};

typedef std::vector<Foo*> FooVector;
typedef boost::indirect_iterator<FooVector::iterator> Adaptor;

int main()
{

    FooVector vec;

    vec.push_back(new Foo("bqq"));
    vec.push_back(new Foo("aqq"));
    vec.push_back(new Foo("cqq"));

    std::sort(Adaptor(vec.begin()), Adaptor(vec.end()));

    std::transform(vec.begin(), vec.end(), std::ostream_iterator<std::string>(std::cout, " "), mem_fun(&Foo::getName));
    std::cout << std::endl;

};

1 użytkowników online, w tym zalogowanych: 0, gości: 1