OVH Cloud OVH Cloud

std::sort sur vecteur de pointeurs

17 réponses
Avatar
Michael
Bonsoir à tous,

je ne parviens pas à trouver quel doit être le troisième argument de
std::sort pour trier un vecteur de la sorte:

class foo
{
private:
int index;
public:
foo(int new_index) : index(new_index) {}
bool operator<(const foo & compar) const { return index <
compar.index; }
int Get_Index() { return index; }
};

class toto
{
private:
std::vector<foo *> liste;
public:
toto();
void Trie();
};


toto::toto()
{
liste.push_back(new foo(8));
liste.push_back(new foo(5));
liste.push_back(new foo(6));
liste.push_back(new foo(1));
liste.push_back(new foo(0));

Trie();
}

void toto:Trie()
{
std::sort(liste.begin(),liste.end(),??);
}

Bien évidemment l'operator< ne fonctionne pas...

Comment puis-je donc faire?

Merci d'avance

Mike

10 réponses

1 2
Avatar
Fabien LE LEZ
On 11 Jan 2005 23:23:09 GMT, Michael
:

je ne parviens pas à trouver quel doit être le troisième argument de
std::sort pour trier un vecteur de la sorte:


Je suis sûr qu'il y a déjà quelque chose de tout fait dans la STL,
mais à défaut de le trouver, tu peux toujours bricoler rapidement :

template <class T> struct CompareObjetsPointes
{
bool operator() (T const* ptr1, T const* ptr2) const
{ return *ptr1 < *ptr2; }
};

void toto:Trie()
{
std::sort(liste.begin(),liste.end(), CompareObjetsPointes());
}


--
;-)

Avatar
Loïc Joly
Michael wrote:

Bonsoir à tous,

je ne parviens pas à trouver quel doit être le troisième argument de
std::sort pour trier un vecteur de la sorte:

class foo
{
private:
int index;
public:
foo(int new_index) : index(new_index) {}
bool operator<(const foo & compar) const { return index <
compar.index; }
int Get_Index() { return index; }
};
[...]

Bien évidemment l'operator< ne fonctionne pas...



class FooPtrComparator
{
bool operator()(foo *f1, foo *f2) {return (*foo1) < (*foo2);}
};

std::sort(liste.begin(),liste.end(),FooPtrComparator);


--
Loïc

Avatar
Michael
Bon je me réponds partiellement à moi même:

class foo
{
private:
int index;
public:
foo(int new_index) : index(new_index) {}
bool operator<(const foo & compar) const { return index <
compar.index; }
int Get_Index() const { return index; }
};

struct CompareByIndex : public std::binary_function<const foo *, const foo
*, bool>
{
bool operator() (const foo * left, const foo * right) const
{ return left->Get_Index() < right->Get_Index(); }
};

CompareByIndex ByIndex() { return CompareByIndex(); }


Et pour trier:
std::sort(liste.begin(),liste.end(),ByIndex());

Seulement j'ai une question: y a-t-il moyen de se passer de la ligne
CompareByIndex ByIndex() { return CompareByIndex(); } et tout mettre dans
la structure?
Avatar
Fabien LE LEZ
On 11 Jan 2005 23:39:11 GMT, Michael
:

struct CompareByIndex

: public std::binary_function<const foo *, const foo *, bool>


Je n'ai jamais bien su si cet héritage sert à quelque chose ou pas. En
tout cas, le "public" n'est guère utile.

{
bool operator() (const foo * left, const foo * right) const
{ return left->Get_Index() < right->Get_Index(); }


Tu as un opérateur foo::<, pourquoi ne pas l'utiliser ?

CompareByIndex ByIndex() { return CompareByIndex(); }
std::sort(liste.begin(),liste.end(),ByIndex());


std::sort(liste.begin(),liste.end(), CompareByIndex ());

Ce qui est à peu près l'équivalent de :

CompareByIndex mon_comparateur;
std::sort(liste.begin(),liste.end(), mon_comparateur );

"CompareByIndex" est une classe, qu'on peut instancier (i.e. créer des
objets "comparateur"), même si dans ce cas précis elle n'a aucune
variable membre.
Un tel objet s'appelle un foncteur.


--
;-)

Avatar
Michael
Désolé, je n'avais pas vu vos réponses...

Merci à tous les deux, ça marche très bien grâce à vous
Avatar
Michael
"CompareByIndex" est une classe, qu'on peut instancier (i.e. créer des
objets "comparateur"), même si dans ce cas précis elle n'a aucune
variable membre.
Un tel objet s'appelle un foncteur.



Merci de m'éclairer là dessus, j'avoue ne jamais avoir trop su ce que
c'était, et un peu fainéant pour me renseigner...

Quoi qu'il en soit j'utilisais déjà des foncteurs notamment pour
std::find_if

Je n'avais pas remarqué qu'il fallait la même chose ici...

Encore merci!

Avatar
kanze
Loïc Joly wrote:
Michael wrote:

je ne parviens pas à trouver quel doit être le troisième
argument de std::sort pour trier un vecteur de la sorte:

class foo
{
private:
int index;
public:
foo(int new_index) : index(new_index) {}
bool operator<(const foo & compar) const { return index <
compar.index; }
int Get_Index() { return index; }
};
[...]

Bien évidemment l'operator< ne fonctionne pas...


class FooPtrComparator
{
bool operator()(foo *f1, foo *f2) {return (*foo1) < (*foo2);}
};

std::sort(liste.begin(),liste.end(),FooPtrComparator);


Étant donné l'utilité, je me démande s'il ne faudrait pas une
version templatée dans toute boîte à outils (à côté de begin et
end sur des tableaux C).

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Michael
Étant donné l'utilité, je me démande s'il ne faudrait pas une
version templatée dans toute boîte à outils (à côté de begin et
end sur des tableaux C).


Par curiosité, ça ressemble à quoi un begin et un end sur des tableaux C?

Avatar
kanze
Michael wrote:
Étant donné l'utilité, je me démande s'il ne faudrait pas
une version templatée dans toute boîte à outils (à côté de
begin et end sur des tableaux C).


Par curiosité, ça ressemble à quoi un begin et un end sur des
tableaux C?


template< typename T, size_t N >
T*
begin( T (&array)[ N ] )
{
return array ;
}

template< typename T, size_t N >
T*
end( T (&array)[ N ] )
{
return array + N ;
}

Et les même en const.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Falk Tannhäuser
Loïc Joly wrote:

class FooPtrComparator
{
bool operator()(foo *f1, foo *f2) {return (*foo1) < (*foo2);}
};

std::sort(liste.begin(),liste.end(),FooPtrComparator);


Et pourquoi pas

struct PtrComparator
{
template<typename T>
bool operator()(T const* a, T const* b) const { return *a < *b; }
};

std::sort(liste.begin(), liste.end(), PtrComparator());

qui fonctionnera pour les pointeurs sur n'importe quel type
supportant l'opérateur < ?

Falk

1 2