OVH Cloud OVH Cloud

Iterateur perso

23 réponses
Avatar
Aurélien REGAT-BARREL
Bonjour,
Me revoilà avec ma classe Triplet, dans ce genre (pour l'exemple) :

struct Triplet
{
int Values[ 3 ];

Triplet( int A, int B, int C )
{
this->Values[ 0 ] = A;
this->Values[ 1 ] = B;
this->Values[ 2 ] = C;
}
};

J'ai un vector de Triplet, je souhaiterais pouvoir lui appliquer des
algorithm tels que max_element, etc... sur
une dimension données des triplets (index 0, 1 ou 2). Quelle est la
meilleure solution ?
J'ai d'abord pensé à un functor d'accès spécial fourni comme comparateur et
l'utilisation de bind1st pour lui
donner la dimension à manipuler, mais je me suis tourné vers un wrapper
d'iterator :

template<typename T>
template<typename T>
class iter_wrapper
{
public:
iter_wrapper( const T & Iter, int Index ):
iter( Iter ), index( Index ) {}

public:
typedef const iter_wrapper<T> const_iterator;

int operator*() const
{
return this->iter->Values[ this->index ];
}

const_iterator& operator++()
{
++this->iter;
return *this;
}

bool operator!=( const const_iterator & _Right ) const
{
return this->iter != _Right.iter;
}

private:
T iter;
int index;
};

template<typename T>
inline iter_wrapper<T> select_index( const T & Iter, int Index )
{
return iter_wrapper<T>( Iter, Index );
}

int main()
{
std::vector<Triplet> v;
v.push_back( Triplet( 0, 1, 0 ) );
v.push_back( Triplet( 0, 2, 0 ) );
v.push_back( Triplet( 0, 3, 0 ) );


int max_b = *std::max_element(
select_index( v.begin(), 1 ),
select_index( v.end(), 1 ) );
}

Qu'en pensez-vous ?
Merci pour votre aide.

--
Aurélien REGAT-BARREL

10 réponses

1 2 3
Avatar
Michel Michaud
Dans news:4121ddcb$0$29616$, Aurélien
Bonjour,
Me revoilà avec ma classe Triplet, dans ce genre (pour
l'exemple) :

struct Triplet
{
int Values[ 3 ];

Triplet( int A, int B, int C )
{
this->Values[ 0 ] = A;
this->Values[ 1 ] = B;
this->Values[ 2 ] = C;
}
};

J'ai un vector de Triplet, je souhaiterais pouvoir lui
appliquer des algorithm tels que max_element, etc... sur
une dimension données des triplets (index 0, 1 ou 2). Quelle
est la meilleure solution ?
J'ai d'abord pensé à un functor d'accès spécial fourni comme
comparateur et l'utilisation de bind1st pour lui donner la
dimension à manipuler,


Je ne vois pas le pourquoi du bind1st ni pourquoi tu dis que
ce serait spécial, mais pour le reste ça me semble la bonne
solution qui permettrait simplement :

... max_element(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(0));

... sort(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(1));

etc.

mais je me suis tourné vers un wrapper d'iterator :
[...]

Qu'en pensez-vous ?


Je vois ce que tu veux faire, mais même si ça pouvait fonctionner,
et ça fonctionnerait pas aussi simplement pour des algorithmes qui
doivent modifier les données -- comme sort par exemple--, ce n'est
pas la façon de faire classique et je ne vois pas pourquoi aller
dans cette voie.

Tu peux expliquer pourquoi tu veux y aller et éviter l'autre ?

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

Avatar
Aurélien REGAT-BARREL
Tu peux expliquer pourquoi tu veux y aller et éviter l'autre ?


Tout simplement parce que je me suis trompé dans la réalisation de mon
functor. Le problème de mon bind1st est que je passais l'index dans le
foncteur lui même, au lieu du cosntructeur :

struct TripletLess : std::binary_function<Triplet, Triplet, bool>
{
inline bool operator()( int Index, const Triplet & T1, const Triplet &
T2 )
{
return T1.Values[ Index ] < T2.Values[ Index ];
}
};

au lieu de, si j'ai un peu mieux réfléchi :

class TripletLess : std::binary_function<Triplet, Triplet, bool>
{
public:
TripletLess( int Index ) : _index( Index ) { /* vérifications de Index
*/ }

inline bool operator()( const Triplet & T1, const Triplet & T2 )
{
return T1.Values[ this->_index ] < T2.Values[ this->_index ];
}

private:
const int _index;
};

Merci Michel.

--
Aurélien REGAT-BARREL

Avatar
Michel Michaud
Dans news:412316df$0$29677$, Aurélien
class TripletLess : std::binary_function<Triplet, Triplet, bool>
{
public:
TripletLess( int Index ) : _index( Index ) { /*
vérifications de Index */ }

inline bool operator()( const Triplet & T1, const Triplet &
T2 ) {
return T1.Values[ this->_index ] < T2.Values[
this->_index ]; }


Je peux comprendre tes « this-> », à la limite tes « _ » en préfixe
et tes majuscules aux noms de paramètres, mais ton « inline » est
vraiment inutile...

Merci Michel.


De rien :-)

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

Avatar
kanze
"Michel Michaud" wrote in message
news:<XVzUc.19799$...
Dans news:4121ddcb$0$29616$, Aurélien

Me revoilà avec ma classe Triplet, dans ce genre (pour
l'exemple) :

struct Triplet
{
int Values[ 3 ];

Triplet( int A, int B, int C )
{
this->Values[ 0 ] = A;
this->Values[ 1 ] = B;
this->Values[ 2 ] = C;
}
};

J'ai un vector de Triplet, je souhaiterais pouvoir lui appliquer des
algorithm tels que max_element, etc... sur une dimension données des
triplets (index 0, 1 ou 2). Quelle est la meilleure solution ?

J'ai d'abord pensé à un functor d'accès spécial fourni comme
comparateur et l'utilisation de bind1st pour lui donner la dimension
à manipuler,


Je ne vois pas le pourquoi du bind1st ni pourquoi tu dis que ce serait
spécial, mais pour le reste ça me semble la bonne solution qui
permettrait simplement :

... max_element(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(0));

... sort(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(1));


Les algorithmes ne s'intéressent pas qu'à l'ordre (même si c'était le
cas des algorithmes qu'il a cité). Comment ferais-tu pour
std::accumulate le nième élément ?

Les deux algorithmes sont valables, chacun selon le problème à résoudre.

etc.

mais je me suis tourné vers un wrapper d'iterator :
[...]

Qu'en pensez-vous ?


Je vois ce que tu veux faire, mais même si ça pouvait fonctionner, et
ça fonctionnerait pas aussi simplement pour des algorithmes qui
doivent modifier les données -- comme sort par exemple--, ce n'est pas
la façon de faire classique et je ne vois pas pourquoi aller dans
cette voie.


L'utilisation d'une projection, implémentée à travers un itérateur, est
une façon classique dans beaucoup de cercles. Je le fais souvent
moi-même. Moins avec les itérateurs STL qu'avec de vrais itérateurs,
c'est vrai, parce que les itérateurs STL sont assez mal conçus pour ce
genre de chose, et exige beaucoup de code pour peu de chose. Les auteurs
de Boost, aussi, sont apparamment de mon avis, parce qu'ils ont
implémenté du support pour l'idiome : voir boost::transform_iterator,
par exemple.

Je crois, en fait, que boost::transform_iterator est exactement ce qu'il
cherche. Il suffit qu'il écrive un objet fonctionnel ExtractNth, et le
tour est joué.

--
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
kanze
"Michel Michaud" wrote in message
news:<XVzUc.19799$...
Dans news:4121ddcb$0$29616$, Aurélien

Me revoilà avec ma classe Triplet, dans ce genre (pour
l'exemple) :

struct Triplet
{
int Values[ 3 ];

Triplet( int A, int B, int C )
{
this->Values[ 0 ] = A;
this->Values[ 1 ] = B;
this->Values[ 2 ] = C;
}
};

J'ai un vector de Triplet, je souhaiterais pouvoir lui appliquer des
algorithm tels que max_element, etc... sur une dimension données des
triplets (index 0, 1 ou 2). Quelle est la meilleure solution ?

J'ai d'abord pensé à un functor d'accès spécial fourni comme
comparateur et l'utilisation de bind1st pour lui donner la dimension
à manipuler,


Je ne vois pas le pourquoi du bind1st ni pourquoi tu dis que ce serait
spécial, mais pour le reste ça me semble la bonne solution qui
permettrait simplement :

... max_element(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(0));

... sort(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(1));


Les algorithmes ne s'intéressent pas qu'à l'ordre (même si c'était le
cas des algorithmes qu'il a cité). Comment ferais-tu pour
std::accumulate le nième élément ?

Les deux algorithmes sont valables, chacun selon le problème à résoudre.

etc.

mais je me suis tourné vers un wrapper d'iterator :
[...]

Qu'en pensez-vous ?


Je vois ce que tu veux faire, mais même si ça pouvait fonctionner, et
ça fonctionnerait pas aussi simplement pour des algorithmes qui
doivent modifier les données -- comme sort par exemple--, ce n'est pas
la façon de faire classique et je ne vois pas pourquoi aller dans
cette voie.


L'utilisation d'une projection, implémentée à travers un itérateur, est
une façon classique dans beaucoup de cercles. Je le fais souvent
moi-même. Moins avec les itérateurs STL qu'avec de vrais itérateurs,
c'est vrai, parce que les itérateurs STL sont assez mal conçus pour ce
genre de chose, et exige beaucoup de code pour peu de chose. Les auteurs
de Boost, aussi, sont apparamment de mon avis, parce qu'ils ont
implémenté du support pour l'idiome : voir boost::transform_iterator,
par exemple.

Je crois, en fait, que boost::transform_iterator est exactement ce qu'il
cherche. Il suffit qu'il écrive un objet fonctionnel ExtractNth, et le
tour est joué.

--
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
kanze
"Michel Michaud" wrote in message
news:<XVzUc.19799$...
Dans news:4121ddcb$0$29616$, Aurélien

Me revoilà avec ma classe Triplet, dans ce genre (pour
l'exemple) :

struct Triplet
{
int Values[ 3 ];

Triplet( int A, int B, int C )
{
this->Values[ 0 ] = A;
this->Values[ 1 ] = B;
this->Values[ 2 ] = C;
}
};

J'ai un vector de Triplet, je souhaiterais pouvoir lui appliquer des
algorithm tels que max_element, etc... sur une dimension données des
triplets (index 0, 1 ou 2). Quelle est la meilleure solution ?

J'ai d'abord pensé à un functor d'accès spécial fourni comme
comparateur et l'utilisation de bind1st pour lui donner la dimension
à manipuler,


Je ne vois pas le pourquoi du bind1st ni pourquoi tu dis que ce serait
spécial, mais pour le reste ça me semble la bonne solution qui
permettrait simplement :

... max_element(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(0));

... sort(v.begin(), v.end(),
TripletEnOrdreDeLaDonnee(1));


Les algorithmes ne s'intéressent pas qu'à l'ordre (même si c'était le
cas des algorithmes qu'il a cité). Comment ferais-tu pour
std::accumulate le nième élément ?

Les deux algorithmes sont valables, chacun selon le problème à résoudre.

etc.

mais je me suis tourné vers un wrapper d'iterator :
[...]

Qu'en pensez-vous ?


Je vois ce que tu veux faire, mais même si ça pouvait fonctionner, et
ça fonctionnerait pas aussi simplement pour des algorithmes qui
doivent modifier les données -- comme sort par exemple--, ce n'est pas
la façon de faire classique et je ne vois pas pourquoi aller dans
cette voie.


L'utilisation d'une projection, implémentée à travers un itérateur, est
une façon classique dans beaucoup de cercles. Je le fais souvent
moi-même. Moins avec les itérateurs STL qu'avec de vrais itérateurs,
c'est vrai, parce que les itérateurs STL sont assez mal conçus pour ce
genre de chose, et exige beaucoup de code pour peu de chose. Les auteurs
de Boost, aussi, sont apparamment de mon avis, parce qu'ils ont
implémenté du support pour l'idiome : voir boost::transform_iterator,
par exemple.

Je crois, en fait, que boost::transform_iterator est exactement ce qu'il
cherche. Il suffit qu'il écrive un objet fonctionnel ExtractNth, et le
tour est joué.

--
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
Aurélien REGAT-BARREL
Je crois, en fait, que boost::transform_iterator est exactement ce qu'il
cherche. Il suffit qu'il écrive un objet fonctionnel ExtractNth, et le
tour est joué.


Je commence doucement à utiliser boost. Je n'ai pas encore regardé
transform_iterator, j'y jetterai un oeil.
Merci.

--
Aurélien REGAT-BARREL

Avatar
Aurélien REGAT-BARREL
Je peux comprendre tes « this-> », à la limite tes « _ » en préfixe
et tes majuscules aux noms de paramètres, mais ton « inline » est
vraiment inutile...


Je ne saurais pas te dire si c'est une initiative personnelle et un
copier-coller. Mais, après l'avoir enlevé, je voudrais être sûr de
comprendre son inutilité : est-ce bien parce que comme c'est une fonction
membre implémentée à l'intérieur de la classe elle est déjà inline, ou
y'a-t-il autre chose ?

--
Aurélien REGAT-BARREL

Avatar
Fabien LE LEZ
On Thu, 19 Aug 2004 14:21:25 +0200, drkm :

J'ai reçu ce message trois fois.


Idem.

--
;-)

Avatar
drkm
writes:

[...]

J'ai reçu ce message trois fois. Cela fait quelques jours que je
reçois plusieurs de tes messages en double. Je me demande si le
problème est de ton côté ou du mien. Que constatent les autres
contributeurs ?

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html
1 2 3