Operateur "|" dans les parametres d'une fonction

Operateur "|" dans les parametres d'une fonction - C++ - Programmation

Marsh Posté le 19-10-2006 à 01:42:29    

Bonjour,
 
Je sais qu'il est possible de passer plusieurs parametres a une methode sans en donner a priori le nombre avec une syntaxe du genre :
 

Code :
  1. void MyObj::MyFunc( int PARAM1 | PARAM2 ...);


 
Le probleme, c'est que je ne sais pas comment traiter, ni declarer ce genre de choses. Pourriez vous m'indiquer un lien ou m'aider a comprendre ce mecanisme ?
 
D'avance merci

Reply

Marsh Posté le 19-10-2006 à 01:42:29   

Reply

Marsh Posté le 19-10-2006 à 06:24:26    

Ya méprise, le pipe '|' n'a rien à voir avec les fonctions variadiques (google: variadic functions).  
Un horrible exemple avec la convention ANSI,

Code :
  1. #include <cstdio>
  2. #include <cstdarg>
  3. void foo(const char * const fmt, ...) {
  4. char buf[56156165161];
  5. va_list vl;
  6. va_start(vl, fmt);
  7.  // va_arg pour aller à la peche aux arguments.
  8.  std::vsprintf(buf, fmt, vl);
  9. va_end(vl);
  10. std::puts(buf);
  11. }


Message édité par tbp le 19-10-2006 à 06:25:07
Reply

Marsh Posté le 19-10-2006 à 15:13:24    

Finalement, j'ai trouve ce que je voulais. Je ne savais pas comment ca s'appelait, donc j'ai du etre mal compris. En tous cas merci.
Ca donne :
 
Un enum pour definir les flags :

Code :
  1. enum criteres_convergence
  2. {
  3. NOMBRE_OBJETS,
  4. NOMBRE_CONNEXIONS,
  5. NOMBRE_CONNEXIONS_SIMPLES,
  6. NOMBRE_CONNEXIONS_DOUBLES,
  7. NOMBRE_CONNEXIONS_MULTIPLES,
  8. ENERGIE_DATA,
  9. ENERGIE_PRIORI
  10. };


 
Le constructeur de la classe (dans le hpp) :

Code :
  1. Convergence_RJMCMC(const PILE <double> &epsilons , const int &tmin , const int &N=100 , const int &ntest=100 , int flags=0);


 
Sa definition (dans le cpp) :

Code :
  1. Convergence_RJMCMC::Convergence_RJMCMC(const PILE <double> &epsilons , const int &tmin , const int &N , const int &ntest , int flags)
  2. {
  3. int nbflag = 0;
  4. if (flags&NOMBRE_OBJETS)
  5. {_flagNombreObjets = 1;nbflag++;}
  6. else
  7.  _flagNombreObjets = 0;
  8. if (flags&NOMBRE_CONNEXIONS)
  9. {_flagNombreConnexions = 1;nbflag++;}
  10. else
  11.  _flagNombreConnexions = 0;
  12. if (flags&NOMBRE_CONNEXIONS_SIMPLES)
  13. {_flagNombreConnexionsSimples = 1;nbflag++;}
  14. else
  15.  _flagNombreConnexionsSimples = 0;
  16. // et ainsi de suite ...
  17. }

Reply

Marsh Posté le 19-10-2006 à 16:11:11    

Heu... là je crois que tu risques d'avoir des soucis :

Citation :

Code :
  1. enum criteres_convergence
  2. {
  3.     NOMBRE_OBJETS,
  4.     NOMBRE_CONNEXIONS,
  5.     NOMBRE_CONNEXIONS_SIMPLES,
  6.     NOMBRE_CONNEXIONS_DOUBLES,
  7.     NOMBRE_CONNEXIONS_MULTIPLES,
  8.     ENERGIE_DATA,
  9.     ENERGIE_PRIORI
  10. };



 
Supposons que cela soit initialisé de telle sorte que :

   NOMBRE_OBJETS = 1,
    NOMBRE_CONNEXIONS = 2,
    NOMBRE_CONNEXIONS_SIMPLES = 3,
...


Dans ce cas, tu as

Code :
  1. (NOMBRE_OBJETS | NOMBRE_CONNEXIONS) == NOMBRE_CONNEXIONS_SIMPLES


...ça ne va pas être joli à voir...
 
Il suffit que tu fasses en sorte que chaque bit corresponde à un message :)


Message édité par bb138 le 19-10-2006 à 16:13:39
Reply

Marsh Posté le 19-10-2006 à 16:50:48    

Merci pour l'info. Alors, je dois faire ca :
 

Code :
  1. enum criteres_convergence
  2. {
  3. NOMBRE_OBJETS 1,
  4. NOMBRE_CONNEXIONS 2,
  5. NOMBRE_CONNEXIONS_SIMPLES 4,
  6. NOMBRE_CONNEXIONS_DOUBLES 8,
  7. NOMBRE_CONNEXIONS_MULTIPLES 16,
  8. ENERGIE_DATA 32,
  9. ENERGIE_PRIORI 64
  10. };


 
ou ca :
 

Code :
  1. #define NOMBRE_OBJETS 1
  2. #define NOMBRE_CONNEXIONS 2
  3. #define NOMBRE_CONNEXIONS_SIMPLES 4
  4. #define NOMBRE_CONNEXIONS_DOUBLES 8
  5. #define NOMBRE_CONNEXIONS_MULTIPLES 16
  6. #define ENERGIE_DATA 32
  7. #define ENERGIE_PRIORI 64


 
Comme ca, je dirai que c'est equivalent ... Non ?

Reply

Marsh Posté le 19-10-2006 à 16:53:17    

Ce n'est pas équivalent car les define sont remplassés à la compilation par le compilateur, les enum non. Mais c'est vrai qu'en soit ça revient au même :)

Reply

Marsh Posté le 19-10-2006 à 17:09:52    

Les enums sont par contre plus propres et plus sûr. Si un enum est remplacé par un int pour une raison x, y ou z, le compilo ralera. Sinon, faut checker au runtime si tu utilises des defines.
Utilise donc les enum sans oublier les '=' ;)

Reply

Marsh Posté le 19-10-2006 à 17:14:36    

A ce stade de la compétition, il serait plus sage de s'en remettre à un bitfield (terme que je n'oserais traduire).

Code :
  1. struct { int en_short:1, en_slip:1, a_prisunic:1; /* etc... */ } tamer;
  2. if (tamer.en_short)
  3. ...
  4. if (tamer.en_slip)
  5. ...
  6. if (tamer.a_prisunic)
  7. ...


Reply

Marsh Posté le 19-10-2006 à 17:18:09    

bb138 a écrit :

Ce n'est pas équivalent car les define sont remplassés à la compilation par le compilateur, les enum non. Mais c'est vrai qu'en soit ça revient au même :)


Bzzt. Les enums sont aussi des constantes à la compilation.

Reply

Marsh Posté le 19-10-2006 à 17:49:56    

(Moi j'ose)
C'est vrai que les champs de bits ça fait joli (j'oublie toujours de les utiliser...)
 
Sinon désolé mais je ne savais pas pour les enum... Ils ne servent donc "qu'à" te signaler tes erreurs à la compilation si je comprend bien (là je suis peut être un peu réducteur).

Reply

Marsh Posté le 19-10-2006 à 17:49:56   

Reply

Marsh Posté le 19-10-2006 à 17:57:05    

Ca sert à ça, mais aussi à limiter un type personnel à un champ de valeur et donc une certaine cohérence.
 
Avec un define, rien ne t'empêche d'utiliser WM_PAINT à la place à la place de NOMBRE_OBJETS.
Ca n'a rien à voir, mais c'est syntaxiquement correct.
 
Donc, par sécurité, il faut utiliser les enum, ou le champ de bit comme l'a dit tbp.

Reply

Marsh Posté le 19-10-2006 à 18:42:46    

Mais aussi,

Code :
  1. template <int n> struct feel_the_powa_t { enum { value = 2*feel_the_powa_t<n-1>::value }; };
  2. template<> struct feel_the_powa_t<0> { enum { value = 1 }; };
  3. int main() { return feel_the_powa_t<4>::value; }


 
Hulahup, barbatruc.

Code :
  1. 00401050 <main>:
  2.   401050:       lea    0x4(%esp),%ecx
  3.   401054:       and    $0xfffffff0,%esp
  4.   401057:       pushl  0xfffffffc(%ecx)
  5.   40105a:       push   %ecx
  6.   40105b:       sub    $0x8,%esp
  7.   40105e:       call   405690 <__main>
  8.   401063:       add    $0x8,%esp
  9.   401066:       mov    $0x10,%eax <--- tada!
  10.   40106b:       pop    %ecx
  11.   40106c:       lea    0xfffffffc(%ecx),%esp
  12.   40106f:       ret


Reply

Marsh Posté le 19-10-2006 à 19:29:40    

Oui, alors justement. Ca sert à autre chose qu'à faire un super "99 bottles of beer" ça? :D
 
(et c'est une question sérieuse ;) )

Reply

Marsh Posté le 19-10-2006 à 22:33:40    

C'est pratique pour génerer des constantes, dérouler des boucles etc... Mais on tombe vite dans l'usine à gaz aux erreurs de compilation taquines qui produit un binaire avec de l'embonpoint. Et puis on peut tjs se gratter pour manipuler des flottants par exemple.
 
Le mot d'ordre, je crois, c'est la parcimonie. http://spirit.sourceforge.net/  :sweat:

Reply

Marsh Posté le 19-10-2006 à 23:03:10    

Merci pour la petite explication :)
Je pense toujours pas l'utiliser de sitôt cela-dit :D


---------------
.
Reply

Marsh Posté le 21-10-2006 à 00:47:51    

tbp a écrit :

C'est pratique pour génerer des constantes, dérouler des boucles etc... Mais on tombe vite dans l'usine à gaz aux erreurs de compilation taquines qui produit un binaire avec de l'embonpoint. Et puis on peut tjs se gratter pour manipuler des flottants par exemple.
 
Le mot d'ordre, je crois, c'est la parcimonie. http://spirit.sourceforge.net/  :sweat:


 
ou pas :o
 
http://forum.hardware.fr/hardwaref [...] 9976-1.htm
http://forum.hardware.fr/hardwaref [...] 9989-1.htm
 
bien coaché (avec des idiomes comme les typelist, les smart pointer et les traits), la meta-*prog tempalte fait des merveilles

Reply

Marsh Posté le 21-10-2006 à 04:09:57    

Joel F a écrit :

bien coaché (avec des idiomes comme les typelist, les smart pointer et les traits), la meta-*prog tempalte fait des merveilles


La meta-prog c'est bien, en abuser ça craint.  
Et ce n'est pas comme si qques ajustements du standard ne se faisaient pas languir, hein.

Reply

Marsh Posté le 21-10-2006 à 09:37:41    

tbp a écrit :


La meta-prog c'est bien, en abuser ça craint.  


 :whistle:  :sol:  
 

tbp a écrit :


Et ce n'est pas comme si qques ajustements du standard ne se faisaient pas languir, hein.


A qui le dit tu :(
export, auto , ou etes vous  :cry:

Reply

Marsh Posté le 21-10-2006 à 12:58:59    

Joel F a écrit :

A qui le dit tu :(
export, auto , ou etes vous  :cry:


Je pense que tbp sous entendait : concepts.
l'inférence de type -- auto, decltype -- ça va figurer au menu de C++0X.
Quand à export, ben comme tu le sais, c'est au standard depuis 8 ans. Il n'y a à ce jour que certains compilateurs utilisant le front end EDG qui le propose (como, icc). Gcc est en train de préparer le terrain pour l'implémenter, et ça ne devrai plus être très long (surement juste avant 2009 quoi!)

Reply

Marsh Posté le 21-10-2006 à 15:40:51    

l'interêt d'un "const int &" est limité quand même ;)

Reply

Marsh Posté le 21-10-2006 à 20:54:57    

++fab a écrit :

Je pense que tbp sous entendait : concepts.
l'inférence de type -- auto, decltype -- ça va figurer au menu de C++0X.
Quand à export, ben comme tu le sais, c'est au standard depuis 8 ans. Il n'y a à ce jour que certains compilateurs utilisant le front end EDG qui le propose (como, icc). Gcc est en train de préparer le terrain pour l'implémenter, et ça ne devrai plus être très long (surement juste avant 2009 quoi!)


 
oui oui ^^ aussi

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed