OVH Cloud OVH Cloud

recherche d'un element suivant la valeur d'un des champs

184 réponses
Avatar
Alain Cabiran
Bonjour,

j'ai cherché, testé, retesté, essayé, réessayé et n'ai pas trouvé
de solution à ce problème

assume using namespace std :-)

imaginons avoir :

class objet
{
public:
objet(int valeur) : monchamps(valeur) { } ;
int getChamps() const { return monchamp; } ;
private:
int monchamps();
};

un conteneur : list<objet> liste;
son iterateur : list<objet>::iterator it;

une valeur prédéfinie : int valeur = 5;

est-ce qu'il est possible, en utilisant les adaptateurs stl,
d'avoir l'équivalent de :

cherche dans liste le premier élément avec la condition
it->monchamp == valeur ?

j'ai commencé par :

it = find_if(liste.begin(), liste.end(), TOTO);

ensuite j'ai cherché TOTO : bind2nd(equal_to<int>(), valeur)

et là ... je sais pas, j'ai essayé de placer :

mem_fun_ref(&objet::getChamps) mais je n'ai pas trouvé où le mettre
et même si je peux seulement l'y mettre.

quelqu'un a une idée ?

Alain Cabiran

ps: il manque évidemment le constructeur de copie, les operateurs de
comparaisons, ... dans la classe, c'est juste pour faire plus court.

10 réponses

1 2 3 4 5
Avatar
Fabien LE LEZ
On Sun, 03 Oct 2004 17:08:57 +0200, Alain Cabiran :

class objet
{
public:
int getChamps() const { return monchamp; } ;

quelqu'un a une idée ?


Je dois dire que je suis assez mauvais sur ce domaine, et je suis sûr
que quelqu'un saura t'écrire la bonne "formule".
Mais est-ce que ça ne serait pas plus clair[*] sans utiliser la grosse
artillerie des adaptateurs ?

class EgaliteChamp
{
public:
EgaliteChamp (int valeur) : reference (valeur) {}
bool operator () (objet o) const { return o.getChamps()==reference; }
private:
int reference;
};


it = find_if (liste.begin(), liste.end(), EgaliteChamp (valeur));

Note : il m'arrive de mettre EgaliteChamp comme membre de la classe
objet.

[*] Ceci n'est pas une question rhétorique. Par contre, ce me semble
une question assez subjective.


--
;-)

Avatar
Alain Cabiran
On Sun, 03 Oct 2004 17:08:57 +0200, Alain Cabiran :


class objet
{
public:
int getChamps() const { return monchamp; } ;



quelqu'un a une idée ?



Je dois dire que je suis assez mauvais sur ce domaine, et je suis sûr
que quelqu'un saura t'écrire la bonne "formule".
Mais est-ce que ça ne serait pas plus clair[*] sans utiliser la grosse
artillerie des adaptateurs ?

class EgaliteChamp
{
public:
EgaliteChamp (int valeur) : reference (valeur) {}
bool operator () (objet o) const { return o.getChamps()==reference; }
private:
int reference;
};


it = find_if (liste.begin(), liste.end(), EgaliteChamp (valeur));

Note : il m'arrive de mettre EgaliteChamp comme membre de la classe
objet.

[*] Ceci n'est pas une question rhétorique. Par contre, ce me semble
une question assez subjective.




C'est ce que j'avais fait à la base, je cherche juste à savoir si c'est
possible avec les adaptateurs et comment, ça me permettra aussi de
savoir si je peux éviter de créer une classe spéciale pour chaque
comparaison.

Uniquement de la technique stl quoi, comme pour un problème de math, je
recense les outils dont je dispose et je prend le(s) meilleur(s). Pour
l'instant je n'ai qu'un seul outil pour comparer des champs, la classe
externe (je crois que ça s'appelle le foncteur), ça fait pas beaucoup
:-).

En plus je n'arrive pas à trouver d'exemple d'utilisation de mem_fun en
dehors de for_each. et il n'est spécifié nulle part que ça ne sert que
pour cet algorithme (me trompe-je ?)...

Alain Cabiran


Avatar
Loïc Joly
Alain Cabiran wrote:
Bonjour,

j'ai cherché, testé, retesté, essayé, réessayé et n'ai pas trouvé
de solution à ce problème

assume using namespace std :-)

imaginons avoir :

class objet
{
public:
objet(int valeur) : monchamps(valeur) { } ;
int getChamps() const { return monchamp; } ;
private:
int monchamps();
};

un conteneur : list<objet> liste;
son iterateur : list<objet>::iterator it;

une valeur prédéfinie : int valeur = 5;

est-ce qu'il est possible, en utilisant les adaptateurs stl,
d'avoir l'équivalent de :

cherche dans liste le premier élément avec la condition
it->monchamp == valeur ?

j'ai commencé par :

it = find_if(liste.begin(), liste.end(), TOTO);

ensuite j'ai cherché TOTO : bind2nd(equal_to<int>(), valeur)

et là ... je sais pas, j'ai essayé de placer :

mem_fun_ref(&objet::getChamps) mais je n'ai pas trouvé où le mettre
et même si je peux seulement l'y mettre.

quelqu'un a une idée ?


Vi, il faut un autre adapteur qui n'existe pas dans la STL par défaut,
un composer:

template <typename Fn1, typename Fn2>
struct Composer : unary_function<typename Fn1::argument_type,
typename Fn2::result_type>
{
Fn1 myF1;
Fn2 myF2;
Composer (Fn1 f1, Fn2 f2) : myF1(f1), myF2(f2) {}
result_type operator()(argument_type arg)
{
return myF2(myF1(arg));
}
};

template <typename Fn1, typename Fn2>
Composer<Fn1, Fn2> compose(Fn1 f1, Fn2 f2)
{
return Composer<Fn1, Fn2>(f1, f2);
}

Et après, tu peut écrire :

find_if(liste.begin(), liste.end(),
compose(mem_fun_ref(&objet::getChamps),
bind2nd(equal_to<int>(), valeur)));

Remarque : boost::bind propose une syntaxe que je trouve bien plus
simple (code non testé):

find_if (liste.begin(), liste.end(),
bind(equal<int>(),
valeur,
bind(&objet::getChamp, _1)));


--
Loïc

Avatar
Alain Cabiran
Alain Cabiran wrote:

Bonjour,

j'ai cherché, testé, retesté, essayé, réessayé et n'ai pas trouvé
de solution à ce problème

assume using namespace std :-)

imaginons avoir :

class objet
{
public:
objet(int valeur) : monchamps(valeur) { } ;
int getChamps() const { return monchamp; } ;
private:
int monchamps();
};

un conteneur : list<objet> liste;
son iterateur : list<objet>::iterator it;

une valeur prédéfinie : int valeur = 5;

est-ce qu'il est possible, en utilisant les adaptateurs stl,
d'avoir l'équivalent de :

cherche dans liste le premier élément avec la condition
it->monchamp == valeur ?

j'ai commencé par :

it = find_if(liste.begin(), liste.end(), TOTO);

ensuite j'ai cherché TOTO : bind2nd(equal_to<int>(), valeur)

et là ... je sais pas, j'ai essayé de placer :

mem_fun_ref(&objet::getChamps) mais je n'ai pas trouvé où le mettre
et même si je peux seulement l'y mettre.

quelqu'un a une idée ?



Vi, il faut un autre adapteur qui n'existe pas dans la STL par défaut,
un composer:

template <typename Fn1, typename Fn2>
struct Composer : unary_function<typename Fn1::argument_type,
typename Fn2::result_type>
{
Fn1 myF1;
Fn2 myF2;
Composer (Fn1 f1, Fn2 f2) : myF1(f1), myF2(f2) {}
result_type operator()(argument_type arg)
{
return myF2(myF1(arg));
}
};

template <typename Fn1, typename Fn2>
Composer<Fn1, Fn2> compose(Fn1 f1, Fn2 f2)
{
return Composer<Fn1, Fn2>(f1, f2);
}

Et après, tu peut écrire :

find_if(liste.begin(), liste.end(),
compose(mem_fun_ref(&objet::getChamps),
bind2nd(equal_to<int>(), valeur)));

Remarque : boost::bind propose une syntaxe que je trouve bien plus
simple (code non testé):

find_if (liste.begin(), liste.end(),
bind(equal<int>(),
valeur,
bind(&objet::getChamp, _1)));




Un grand Merci pour la solution, je vais aussi jeter un coup d'oeil sur
boost.

Alain Cabiran


Avatar
Michel Michaud
Dans le message 416015fa$0$15751$,
class objet
{
public:
objet(int valeur) : monchamps(valeur) { } ;
int getChamps() const { return monchamp; } ;
private:
int monchamps();
};

un conteneur : list<objet> liste;
son iterateur : list<objet>::iterator it;

une valeur prédéfinie : int valeur = 5;

est-ce qu'il est possible, en utilisant les adaptateurs stl,


Tu veux dire ce qu'il y a dans la bibliothèque standard je
suppose...

d'avoir l'équivalent de :

cherche dans liste le premier élément avec la condition
it->monchamp == valeur ?


Non, mais avec des choses de boost (compose ?), je crois que
tu pourrais. Je ne suis pas encore spécialiste de boost par
contre...

Mais c'est facile avec une fonction objet :

class ChercherValeur
{
public :
ChercherValeur(int p_valeurCherchée)
: m_valeurCherchée(p_valeurCherchée)
{}

bool operator()(const objet& p_obj) const
{ return p_obj.getChamps() == m_valeurCherchée; }

private :
int m_valeurCherchée;
};

... it= find_if(l.begin(), l.end(), ChercherValeur(valeur));

P.S. Pour ceux qui se posent la question : j'ai mis les accents
intentionnellement dans mon code. Il faut partir la mode
maintenant que c'est enfin possible avec un compilateur
(VC++ 2005... beta !) afin de pousser les autres à respecter
la norme sur ce sujet si simple il me semble...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

[...]

| P.S. Pour ceux qui se posent la question : j'ai mis les accents
| intentionnellement dans mon code. Il faut partir la mode
| maintenant que c'est enfin possible avec un compilateur
| (VC++ 2005... beta !) afin de pousser les autres à respecter
| la norme sur ce sujet si simple il me semble...

Si simple ? Ahem.

-- Gaby
Avatar
Michel Michaud
Dans le message ,
"Michel Michaud" writes:

[...]

P.S. Pour ceux qui se posent la question : j'ai mis les accents
intentionnellement dans mon code. Il faut partir la mode
maintenant que c'est enfin possible avec un compilateur
(VC++ 2005... beta !) afin de pousser les autres à respecter
la norme sur ce sujet si simple il me semble...


Si simple ? Ahem.


:-)

Tout est relatif bien entendu.

Mais est-ce plus difficile que export ou le Koenig lookup ? (À
mon dernier essai, les accents ne fonctionnaient pas avec Como,
alors que export fonctionnait ! Ça a peut-être changé... Pour
moi, les accents sont plus utiles que export, mais je comprends
que ce ne soit pas la priorité de tout le monde.)

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
Fabien LE LEZ
On Sun, 3 Oct 2004 22:46:42 -0400, "Michel Michaud" :

j'ai mis les accents intentionnellement dans mon code
[...] sur ce sujet si simple il me semble...


Vu le bordel que c'est sur Usenet-fr, alors que ça existe depuis des
années, je doute que ça donne grand-chose avant pas mal d'années.

Dans ton message suivant :

Pour moi, les accents sont plus utiles que export


Pour toi en tant que programmeur ou en tant que prof ?


En fait, je me demande s'il est judicieux d'écrire en français dans du
code de production. En effet, je peux être à peu près sûr que celui
qui reprendra mon code saura lire l'anglais, tandis que je ne peux pas
savoir à l'avance s'il sera francophone.




--
;-)

Avatar
Twxs
Michel Michaud wrote:




P.S. Pour ceux qui se posent la question : j'ai mis les accents
intentionnellement dans mon code. Il faut partir la mode
maintenant que c'est enfin possible avec un compilateur
(VC++ 2005... beta !) afin de pousser les autres à respecter
la norme sur ce sujet si simple il me semble...

si on ecrit en francais avec les accents, ne faut il pas remplacer

getChamps par qqchose de moins hybride ;)

Twxs

Avatar
Fabien LE LEZ
On Mon, 04 Oct 2004 14:42:26 +0200, Twxs :

si on ecrit en francais avec les accents, ne faut il pas remplacer
getChamps par qqchose de moins hybride ;)


Je ne considère pas les mots "get" et "set", du moins en début
d'identifiant, comme des mots anglais. Ce sont des mots du vocabulaire
informatique (comme "template" par exemple), que j'utilise aussi bien
en français qu'en anglais.
Par contre, j'avoue que je déteste la convention "Java" pour les
majuscules.


--
;-)

1 2 3 4 5