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.
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)
On 2008-11-06, Alain Ketterlin <alain@dpt-info.u-strasbg.fr> 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 :
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)
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)
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.
Fabien LE LEZ <gramster@gramster.com> writes:
On Fri, 07 Nov 2008 11:41:08 +0100, Alain Ketterlin
<alain@dpt-info.u-strasbg.fr>:
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*>.)
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.
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__
Fabien LE LEZ <gramster@gramster.com> writes:
On Fri, 07 Nov 2008 12:18:11 +0100, pjb@informatimago.com (Pascal J.
Bourguignon):
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.
pjb@informatimago.com (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:
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.
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.
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.
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.
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.