L'enfer de la STL

Le
Alain Ketterlin
Salut,

J'utilise pas mal la STL, avec des combinaisons du genre :

map < pair<Truc*,Truc*> , set<Truc*> > m;

(pour la plus simple). Pour diverses raisons, j'essaie d'éviter les
typedef. Donc je me retrouve avec des boucles comme :

for ( map < pair<Truc*,Truc*> , set<Truc*> >::iterator it=m.begin() ;
it!=m.end() ; it++ )
{ }

D'où mes deux questions :

1) y a-t-il plus court ? (Hors for_each, qui ne m'intéresse pas parce
que mes corps de boucle sont éventuellement longs, et je n'ai pas
envie de les rejeter chacun dans une classe.)

2) Quelqu'un a-t-il des informations sur la standardisation
(éventuelle) et l'implémentation de "auto" dans g++ ? Je n'ai rien
trouvé de précis. Quand pourrais-je écrire
for ( auto it=m.begin() ; it!=m.end() ; it++ )


Question subsidiaire : en essayant d'écrire une macro pour remplacer
la tête de boucle ci-dessus, j'ai remarqué que le préprocesseur ne
connait rien aux templates. Si j'écris

#define FOREACH(T,c,v) for ( T :: iterator v=c.begin() )

alors il couine sur

FOREACH(pair<Truc1,Truc2>,m,it)

parce qu'il ne comprend pas que la première virgule est entre < et >.
Savez-vous si il est prévu que ça change ?

Merci d'avance. J'espère avoir raté quelque chose d'évident.

-- Alain.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #17767021
Alain Ketterlin
J'utilise pas mal la STL, avec des combinaisons du genre :

map < pair<Truc*,Truc*> , set<Truc*> > m;

(pour la plus simple). Pour diverses raisons, j'essaie d'éviter les
typedef. Donc je me retrouve avec des boucles comme :

for ( map < pair<Truc*,Truc*> , set<Truc*> >::iterator it=m.begin() ;
it!=m.end() ; it++ )
{ ... }

D'où mes deux questions :

1) y a-t-il plus court ? (Hors for_each, qui ne m'intéresse pas parce
que mes corps de boucle sont éventuellement longs, et je n'ai pas
envie de les rejeter chacun dans une classe.)



Pas que je sache.

Question subsidiaire : en essayant d'écrire une macro pour remplacer
la tête de boucle ci-dessus, j'ai remarqué que le préprocesseur ne
connait rien aux templates. Si j'écris

#define FOREACH(T,c,v) for ( T :: iterator v=c.begin() ... )

alors il couine sur

FOREACH(pair<Truc1,Truc2>,m,it)

parce qu'il ne comprend pas que la première virgule est entre < et >.
Savez-vous si il est prévu que ça change ?



Il n'est pas prevu que ca change (conceptuellement le preprocesseur
fonctionne a un moment ou il est impossible de savoir si pair est un
template ou pas.

Sauf erreur de ma part,

FOREACH((pair<Truc1,Truc2>), m, it)

devrait fonctionner.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alain Ketterlin
Le #17767131
Jean-Marc Bourguet
Alain Ketterlin
#define FOREACH(T,c,v) for ( T :: iterator v=c.begin() ... )

alors il couine sur

FOREACH(pair<Truc1,Truc2>,m,it)

parce qu'il ne comprend pas que la première virgule est entre < et >.
Savez-vous si il est prévu que ça change ?



Il n'est pas prevu que ca change (conceptuellement le preprocesseur
fonctionne a un moment ou il est impossible de savoir si pair est un
template ou pas.



Oh j'espérais plus simple, du genre considérer comme atomique ce qui
se trouve entre < et >, comme il le fait avec ( et ). Ca pourrait être
une option, puique GNU cpp a déjà -x et -std.

Sauf erreur de ma part,

FOREACH((pair<Truc1,Truc2>), m, it)

devrait fonctionner.



Malheureusement non, impossible de caser un type entre parenthèse.

Merci pour ton aide.

-- Alain.
Jean-Marc Bourguet
Le #17767541
Alain Ketterlin
Jean-Marc Bourguet
> Alain Ketterlin >> #define FOREACH(T,c,v) for ( T :: iterator v=c.begin() ... )
>>
>> alors il couine sur
>>
>> FOREACH(pair<Truc1,Truc2>,m,it)
>>
>> parce qu'il ne comprend pas que la première virgule est entre < et >.
>> Savez-vous si il est prévu que ça change ?
>
> Il n'est pas prevu que ca change (conceptuellement le preprocesseur
> fonctionne a un moment ou il est impossible de savoir si pair est un
> template ou pas.

Oh j'espérais plus simple, du genre considérer comme atomique ce qui
se trouve entre < et >, comme il le fait avec ( et ). Ca pourrait être
une option, puique GNU cpp a déjà -x et -std.

> Sauf erreur de ma part,
>
> FOREACH((pair<Truc1,Truc2>), m, it)
>
> devrait fonctionner.

Malheureusement non, impossible de caser un type entre parenthèse.



Il y a des endroits dans les types ou on peut mettre des parentheses,
mais pas dans ce qui qualifie les noms.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Fabien LE LEZ
Le #17770161
On Thu, 06 Nov 2008 17:29:52 +0100, Alain Ketterlin

map < pair<Truc*,Truc*> , set<Truc*> > m;



typedef est ton ami.
Mickaël Wolff
Le #17770501
Alain Ketterlin a écrit :
(pour la plus simple). Pour diverses raisons, j'essaie d'éviter les
typedef. Donc je me retrouve avec des boucles comme :



Quels peuvent être les raisons qui peuvent pousser à ne pas employer
une technique propre ?

2) Quelqu'un a-t-il des informations sur la standardisation
(éventuelle) et l'implémentation de "auto" dans g++ ? Je n'ai rien
trouvé de précis. Quand pourrais-je écrire
for ( auto it=m.begin() ; it!=m.end() ; it++ ) ...



Ce n'est visiblement pas encore implémenté


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Alp Mestan
Le #17772091
Il ne faut pas oublier Boost, qui propose un FOREACH assez
intelligent, et qui permet de créer des lambdas expressions.
Ca donne quelque chose comme, avec le for_each de la STL :
for_each(m.begin(), m.end(), cout << _1 << endl);
Cela affichera tous les éléments de m, ou m est un peu ce que tu veux,
pour peu que ses éléments soient affichables.
Alain Ketterlin
Le #17772501
Mickaël Wolff
Alain Ketterlin a écrit :
(pour la plus simple). Pour diverses raisons, j'essaie d'éviter les
typedef. Donc je me retrouve avec des boucles comme :



Quels peuvent être les raisons qui peuvent pousser à ne pas employer
une technique propre ?



Mon grand age. Quand j'ai une boucle comme :

for ( map < pair<Truc*,Truc*> , set<Truc*> >::iterator it=m.begin() ;
it!=m.end() ; it++ )
{ ... }

le corps de la boucle contient des choses du genre :

... it->first.second ...

Je préfère avoir le type détaillé sous les yeux, plutôt que d'aller
chercher le typedef correspondant. Je n'ai jamais trouvé typedef très
utile (sauf en C), et j'ai tendance à penser que ce n'est guère plus
qu'un prépro. Quitte à être propre, quand c'est nécessaire je définis
une classe, mais alors je suis parti pour le rodéo copy-ctor/op= etc.
Bien sûr tout cela est très subjectif.

Cela dit, au risque d'être sacrilège, pour une boucle comme celle
ci-dessus, le panard ça serait :

for ( entry < pair<Truc*,Truc*> , set<Truc*> > e : m )
{ ... }

ou quelque chose comme cela, mais ça demande une nouvelle syntaxe.

2) Quelqu'un a-t-il des informations sur la standardisation
(éventuelle) et l'implémentation de "auto" dans g++ ? Je n'ai rien
trouvé de précis. Quand pourrais-je écrire
for ( auto it=m.begin() ; it!=m.end() ; it++ ) ...



Ce n'est visiblement pas encore implémenté



Cool. Dans gcc-4.4 ils auront déjà supprimé l'ancien auto, mais sans
ajouter le nouveau. Un premier pas :-)

-- Alain.
Fabien LE LEZ
Le #17772641
On Fri, 07 Nov 2008 11:41:08 +0100, Alain Ketterlin

Je préfère avoir le type détaillé sous les yeux,



Faudrait savoir.

Avec
for ( auto it=m.begin() ; it!=m.end() ; it++ ) ...
tu ne l'as pas plus sous les yeux !


Quitte à être propre, quand c'est nécessaire je définis
une classe,



Effectivement, les types à rallonge du style map<set<... sont
généralement "locaux", utilisés dans une seule fonction ou dans un
petit groupe de fonctions. Du coup, le typedef est très proche du
code, pas besoin d'aller très loin pour le trouver.

Si j'ai besoin d'un tel type dans un contexte plus global (= défini
dans un .h), je l'encapsule dès le départ dans une classe -- parce que
j'en aurai besoin tôt ou tard.

mais alors je suis parti pour le rodéo copy-ctor/op= etc.



Je ne vois pas pourquoi.

Si les constructeur et opérateur de copie du type

map < pair<Truc*,Truc*> , set<Truc*> >

te conviennent, alors ceux de

class C
{
...
private:
map < pair<Truc*,Truc*> , set<Truc*> > data;
};

devraient te convenir aussi.
pjb
Le #17772741
Alain Ketterlin
Cela dit, au risque d'être sacrilège, pour une boucle comme celle
ci-dessus, le panard ça serait :

for ( entry < pair<Truc*,Truc*> , set<Truc*> > e : m )
{ ... }

ou quelque chose comme cela, mais ça demande une nouvelle syntaxe.



D'où l'intérêt d'un langage comme Common Lisp qui permet de définir
facilement des nouvelles syntaxes.




Sinon il faut utiliser boost:

// Boost 1.33.3 ; dans boost 1.34, foreach n'est plus "test".
#include #define foreach BOOST_TEST_FOREACH

Ainsi, si on a un conteneur contenant des élément de type Type, on peut écrire:

foreach(Type,element,conteneur){
process(element);
}


--
__Pascal Bourguignon__
Fabien LE LEZ
Le #17772831
On Fri, 07 Nov 2008 12:18:11 +0100, (Pascal J.
Bourguignon):

D'où l'intérêt d'un langage comme Common Lisp



Tiens, ça faisait longtemps...
Publicité
Poster une réponse
Anonyme