Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

L'enfer de la STL

27 réponses
Avatar
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.

10 réponses

1 2 3
Avatar
Marc Boyer
On 2008-11-06, Alain Ketterlin wrote:

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++ )
{ ... }



Et oui, moi j'utilise beaucoup les typedef. En fait, un type, c'est
souvent un choix de représentation d'un membre. Donc je définis
le nom en fonction du nom du membre.
Des choses comme ça
class X {
typedef map < pair<Truc*,Truc*> , set<Truc*> > t_annuaireMachin;
t_AnnuaireMachin annuaireMachin;
};

D'où un code
for ( t_m:iterator it=m.begin() ; it!=m.end() ; it++ )

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Alain Ketterlin
Fabien LE LEZ writes:

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 !



Ouais, je croyais l'avoir précisé. En fait je pensais surtout à "auto"
pour pouvoir écrire une macro FOREACH, ce qu'on ne peut pas faire à
cause des faiblesses de prepro. auto aurait permis de contourner.

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.



J'entends : du coup, pas besoin de typedef :-). Ton argument tient,
c'est juste que j'ai peu de gout pour typedef.

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.



Mais je ne peux pas écrire c1 = c2 (avec deux instances de C) sans
risque.

(Là encore, je pensais aux types "internes", comme pair<Truc*,Truc*>.)

-- Alain.
Avatar
pjb
Fabien LE LEZ writes:

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...



Deux semaines de vacances ;-)


--
__Pascal Bourguignon__
Avatar
Marc
Mickaël Wolff wrote:

[discussion sur "auto"]
Ce n'est visiblement pas encore implémenté
<http://gcc.gnu.org/projects/cxx0x.html>



En fait si :
http://gcc.gnu.org/ml/libstdc++/2008-10/msg00087.html
Avatar
Alain Ketterlin
(Pascal J. Bourguignon) writes:

// Boost 1.33.3 ; dans boost 1.34, foreach n'est plus "test".
#include <boost/test/utils/foreach.hpp>
#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);
}



En fait foreach( indice, conteneur ), du moins en 1.34. Dans les cas
tordus, il faut toujours déclarer l'indice avant (et donc s'interdire
les références). Par ex. :

vector< pair<int,int> > v = ...;
BOOST_FOREACH( pair<int,int> p, v ) // Boum
{ ... }

mais à cela il n'est rien à faire.

Cela dit, en jetant un coup d'oeil sur le code, je me demande si je ne
vais pas repasser à C... ou à Lisp, tiens.

-- Alain.
Avatar
Mickaël Wolff
Alp Mestan a écrit :
Il ne faut pas oublier Boost


[...]
des lambdas expressions.



C'est l'enfer à utiliser. Je dois être un peu con, mais à chaque fois
que je fait des trucs un peu sophistiquées (comme modifier un élément
pointé par l'itérateur, ou lui ajouter 1), ça ne compile pas. Je préfère
les functors, au moins ça marche ©

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Mickaël Wolff
Pascal J. Bourguignon a écrit :

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



Tu commences à me gonfler. Si LISP est un langage si parfait, ignores
le C++ et arrêter de nous les briser. Certainement que LISP a des
qualités, mais c'est pas avec ce genre d'interventions pénibles que tu
vas attirer du monde dans ta chapelle.

Fin de la parenthèse ? :D


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Mickaël Wolff
Marc a écrit :

En fait si :
http://gcc.gnu.org/ml/libstdc++/2008-10/msg00087.html



Qu'y a-t-il de pire qu'une documentation absente ? ;)

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Fabien LE LEZ
On Fri, 07 Nov 2008 12:45:56 +0100, Alain Ketterlin
:

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






Mais je ne peux pas écrire c1 = c2 (avec deux instances de C) sans
risque.



Pourquoi ?
Si tu utilises des pointeurs nus, j'imagine qu'ils référencent des
objets (de classe Truc) qui existe par ailleurs ?

(Note que c'est le même problème avec C qu'avec ton map<...)
Avatar
Olivier Miakinen
Le 07/11/2008 17:36, Mickaël Wolff a écrit :

Qu'y a-t-il de pire qu'une documentation absente ? ;)



Une documentation existante d'une fonction absente ?
1 2 3