OVH Cloud OVH Cloud

Sort STL

27 réponses
Avatar
horneta2005
j essaye de mettre en ouvre une fonction de comparaison pour
std::sort mais d apres les exemple que j ai vu je ne comprend pas
leur fonctionnement notament le role de opeator()

10 réponses

1 2 3
Avatar
Stan
"kanze" a écrit dans le message de
news:
bool
dataOK( std::vector< int > const& v )
{
static int const limit = 5 ;
CondImpl c ;
return std::find_if( v.begin(), v.end(), Cond( &c ) ) = > v.end() ;
}


CondImpl c(limit) ; // je suppose


--
-Stan

Avatar
Fabien LE LEZ
On 5 Oct 2005 09:52:20 -0700, "kanze" :

[...

Si j'en crois <http://www.sgi.com/tech/stl/find_if.html> :
- le prédicat doit être appelé au plus une fois sur chaque
élément ;
- l'itérateur renvoyé est le premier à satisfaire le prédicat ;
- et j'ai l'impression que c'est à peu près tout.

Imaginons un instant l'implémentation suivante de find_if :


InputIterator reponse= last;

Je crée un std::vector<InputIterator>, et je le remplis avec les
itérateurs (ce qui permet de transformer les itérateurs "forward" en
"random") ;

Je parcours ce tableau à l'envers ; si le prédicat renvoie true,
j'assigne ce InputIterator à "reponse" ;

Je renvoie "reponse".


Il me semble que cette implémentation :
- n'utilise que le fait que InputIterator est un "forward" ;
- appelle au plus une fois (en fait, exactement une fois) le
prédicat sur chaque élément ;
- renvoie le premier élément qui satisfasse au prédicat ;
- empêche ton prédicat "Comp" de fonctionner.
Avatar
Fabien LE LEZ
On 5 Oct 2005 09:52:20 -0700, "kanze" :

Est-ce qu'il serait légal ? Est-ce qu'il doit l'être ?


Pourrais-tu m'expliquer la nuance entre ces deux questions ?

Avatar
Fabien LE LEZ
On Wed, 5 Oct 2005 15:43:00 +0200, "Stan" <(remove 1,2,3)
:

Si l'opération est commutative, le pb ne se pose pas, l'exemple
typique est la sommation :

TSum sum(0);

for_each( v.begin( ), v.end( ), sum );


Mauvais contre-exemple AMHA :
- for_each donne, contrairement à d'autres algorithmes, une
garantie sur l'ordre de traitement ;
- la sommation n'est pas forcément commutative
(std::string::operator+ par exemple).

Avatar
kanze
Fabien LE LEZ wrote:
On Wed, 5 Oct 2005 15:43:00 +0200, "Stan" <(remove 1,2,3)
:

Si l'opération est commutative, le pb ne se pose pas, l'exemple
typique est la sommation :

TSum sum(0);

for_each( v.begin( ), v.end( ), sum );


Mauvais contre-exemple AMHA :
- for_each donne, contrairement à d'autres algorithmes, une
garantie sur l'ordre de traitement ;
- la sommation n'est pas forcément commutative
(std::string::operator+ par exemple).


Il y a encore un problème avec son exemple : for_each (comme
tous les algorithmes) prend l'objet fonctionnel par valeur,
c-à-d qu'il en reçoit une copie, et non l'objet initial. Ce qui
veut dire que sum ne serait pas modifié dans l'exemple
ci-dessus.

En fait, la fonction for_each est, je crois, sous-spécifiée. En
lisant la norme, je crois qu'une implémentation :

template< typename Iter, typename Func >
Func
for_each( Iter begin, Iter end, Func f )
{
while ( begin != end ) {
Func tmp = f ;
tmp( *begin ) ;
++ begin ;
}
return f ;
}

serait légal. Or que je crois que l'intention, c'est qu'il n'y a
pas de copie une fois que la boucle a commencé, et qu'on renvoie
une copie de l'instance (unique) qui a servi dans la boucle.
C-à-d que quelque chose comme :

std::cout << for_each( v.begin(), v.end(), TSum(0) ).res()

marchera comme attendu.

Ceci dit, il n'y a pas de mal à donner à l'objet fonctionnel une
sémantique de référence même dans ce cas-ci.

--
James Kanze GABI Software
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
Stan (remove 1,2,3) wrote:
"kanze" a écrit dans le message de
news:
bool
dataOK( std::vector< int > const& v )
{
static int const limit = 5 ;
CondImpl c ;
return std::find_if( v.begin(), v.end(), Cond( &c ) ) ==
v.end() ;
}


CondImpl c(limit) ; // je suppose


Tout à fait.

--
James Kanze GABI Software
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
Fabien LE LEZ wrote:
On 5 Oct 2005 09:52:20 -0700, "kanze" :

[...

Si j'en crois <http://www.sgi.com/tech/stl/find_if.html> :
- le prédicat doit être appelé au plus une fois sur chaque
élément ;
- l'itérateur renvoyé est le premier à satisfaire le prédicat ;
- et j'ai l'impression que c'est à peu près tout.

Imaginons un instant l'implémentation suivante de find_if :

InputIterator reponse= last;

Je crée un std::vector<InputIterator>, et je le remplis avec
les itérateurs (ce qui permet de transformer les itérateurs
"forward" en "random") ;

Je parcours ce tableau à l'envers ; si le prédicat renvoie
true, j'assigne ce InputIterator à "reponse" ;

Je renvoie "reponse".

Il me semble que cette implémentation :
- n'utilise que le fait que InputIterator est un "forward" ;
- appelle au plus une fois (en fait, exactement une fois) le
prédicat sur chaque élément ;
- renvoie le premier élément qui satisfasse au prédicat ;
- empêche ton prédicat "Comp" de fonctionner.


C'est bien. Alors, il faut un input iterator pour garantir le
fonctionnement voulu:-). Ou que je wrappe mon itérateur réel
dans un input iterator:-).

--
James Kanze GABI Software
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
Fabien LE LEZ wrote:
On 5 Oct 2005 09:52:20 -0700, "kanze" :

Est-ce qu'il serait légal ? Est-ce qu'il doit l'être ?


Pourrais-tu m'expliquer la nuance entre ces deux questions ?


La première, c'est : si j'écris du code comme ceci, est-ce qu'il
serait légal, selon la norme, telle qu'elle est actuellement ?
La deuxième, c'est : est-ce que cette réponse correspond
réelement à ce qu'on veut, ou est-ce qu'il ne serait pas mieux
de modifier la norme pour changer la réponse à la première
question ?

La deuxième question a surtout de sens si la réponse à la
première est non. Parce dans les faits, je crois que le code en
question marche avec toutes les implémentations existantes, et
que c'est raisonable à s'attendre à ce qu'il marche.

--
James Kanze GABI Software
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
Stan
"Fabien LE LEZ" a écrit dans le message de news:

On Wed, 5 Oct 2005 15:43:00 +0200, "Stan" <(remove 1,2,3)
:

Si l'opération est commutative, le pb ne se pose pas, l'exemple
typique est la sommation :

TSum sum(0);

for_each( v.begin( ), v.end( ), sum );


Mauvais contre-exemple AMHA :


???

- for_each donne, contrairement à d'autres algorithmes, une
garantie sur l'ordre de traitement ;


C'est justement pour cette raison que je l'ai choisi !

- la sommation n'est pas forcément commutative
(std::string::operator+ par exemple).



Heu...oui, la concaténation n'est pas commutative.
Comment détourner un exemple de façon éhontée ;-)
Relit bien : TSum sum( 0 );
Et non pas : TConcat append( "" );

Pour quel programmeur le mot sommation équivaut à concaténation ?

Bon, comme tu l'as remarqué, je ne suis pas d'accord ;-)

--
-Stan


Avatar
Stan
"kanze" a écrit dans le message de news:


Il y a encore un problème avec son exemple : for_each (comme


Satanné exemple !

tous les algorithmes) prend l'objet fonctionnel par valeur,
c-à-d qu'il en reçoit une copie, et non l'objet initial. Ce qui
veut dire que sum ne serait pas modifié dans l'exemple
ci-dessus.


Ca ne t'arrive jamais d'oublier un truc dans un post ?
Ah non, quand c'est moi, c'est une erreur, et quand c'est toi, c'est un
oubli ou une faute de frappe.

TSum sum(0);
sum = for_each( v.begin( ), v.end( ), sum );
std::cout << "total= " << sum.res( ) << std::endl;

Faut-il que je développe le code de TSum pour
s'assurer qu'elle fonctionne bien ?

--
-Stan

1 2 3