Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1133 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  ça existe un ostream vide/bidon ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

ça existe un ostream vide/bidon ?

n°1890240
Glock 17Pr​o
Posté le 02-06-2009 à 07:55:32  profilanswer
 

ça existe en C++ un stream qui ne fasse rien ?
par exemple pour qu'une ligne suivante consomme le moins possible de CPU:
 
ostream << "message"
 
merci

mood
Publicité
Posté le 02-06-2009 à 07:55:32  profilanswer
 

n°1890250
Joel F
Real men use unique_ptr
Posté le 02-06-2009 à 08:56:00  profilanswer
 

non mais c'est assez simple à faire en héritant de stream je pense

n°1890283
theshockwa​ve
I work at a firm named Koslow
Posté le 02-06-2009 à 10:26:25  profilanswer
 

un ostream qui écrit dans /dev/null ? [:dawa]


---------------
last.fm
n°1890361
Joel F
Real men use unique_ptr
Posté le 02-06-2009 à 12:10:08  profilanswer
 

il ferait qd mm tout son travail en interne. Tu fais un stream qui fait rien dans ses insertions/extractions et zou

n°1890368
Taz
bisounours-codeur
Posté le 02-06-2009 à 12:16:44  profilanswer
 

Même si t'hérites, si tu veux tout transformer en NOP, il faudrait tout redéfinir inline :/

n°1890559
Glock 17Pr​o
Posté le 02-06-2009 à 19:53:37  profilanswer
 

bon j'ai trouvé une autre solution en utilisant les templates, en faite je fais une classe de log avec une gestion de différents level de logs, et il me fallait une feinte pour ne pas prendre en compte des <<'message' quand le level n'est pas suffisament grand

n°1890638
Taz
bisounours-codeur
Posté le 02-06-2009 à 23:38:36  profilanswer
 

Tu ne veux pas plutôt réutiliser de l'existent ?

n°1890641
Glock 17Pr​o
Posté le 03-06-2009 à 00:22:04  profilanswer
 

si c'est assez bien oui,  mais c'est du boost j'imagine ? idéalement j'aurais besoin d'une classe qui sache être hyper performante  pour pouvoir être intégrée dans des applis temps réel, et également user friendly quand il s'agit d'applis moins critiques. La classe de log parfaite quoi en somme :)


Message édité par Glock 17Pro le 03-06-2009 à 00:30:15
n°1890654
Joel F
Real men use unique_ptr
Posté le 03-06-2009 à 07:07:02  profilanswer
 

sauf que genre t'e as le 1er à y penser :E
quant à tes exigences sur le TR .... [:prozac]

n°1890657
Glock 17Pr​o
Posté le 03-06-2009 à 07:36:48  profilanswer
 

ok  :heink:

mood
Publicité
Posté le 03-06-2009 à 07:36:48  profilanswer
 

n°1890721
theshockwa​ve
I work at a firm named Koslow
Posté le 03-06-2009 à 10:31:06  profilanswer
 

si ca correspond à ce que j'ai vu dans tes autres posts, tu calcules  en template un booléen à partir de ton niveau de log, donc pourquoi ne pas avoir une fonction log< bool LevelEstAssezHaut >( const string& message ) qui, quand l'argument template vaut vrai, logge vraiment et quand il vaut faux, ne fait rien ?


---------------
last.fm
n°1890726
Glock 17Pr​o
Posté le 03-06-2009 à 10:47:50  profilanswer
 

voilà c'est ce que je fais mais le 'rien' me poser me problème car grace un #define mon code pour logger  
faisait ainsi :
 
WriteLog(DEBUG) << "message" << i;
WriteLog(CRITIQUE) << "message2";
WriteLog(FLUSH);
 
En faite je résoud mon problème en surchant operator << dans la spécialisation de ma classe template ayant comme paramètre bool = false (booléen calculé grace à une une autre classe template,en se basant sur des const, donc calculable à la compilation) . Je fais juste un return *this dans operator <<  ainsi que dans la méthode appelé pour logger ,comme ça la ligne de tout le code à ne peut pas prendre en compte, par exemple WriteLog(DEBUG) << "message2", car le level demandé est uniquement les messages CRITIQUE,  se limite juste à des appels de fonctions vides.
 

Code :
  1. #include <sstream>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <ctime>   //time
  5. namespace Logger
  6. {
  7. #define WriteLog(level) Log< LogHelper<level>::Value >().Get(level)
  8. /* PARAMETRE */
  9. enum LogLevel {FLUSH,DEBUG,INFO,CRITIQUE};
  10. const char * const path  = "log.txt";
  11. const int reportingLevel = CRITIQUE;
  12. /* END OF PARAMETRE*/
  13.  std::ostringstream      log_buffer;
  14. char* GetTime()
  15. {
  16.  time_t t = time(NULL);
  17.  char * ret=ctime(&t);
  18.  ret[24]='\0'; //on enelve le \n
  19.  return  ret;
  20. }
  21. ///////////////////////////
  22. template<int U> struct LogHelper
  23. {
  24.  enum { Value = ( U >= reportingLevel ) };
  25. };
  26. template<> struct LogHelper<0>
  27. {
  28.  enum { Value = 2};
  29. };
  30. ///////////////////////////
  31. template<int condition> struct Log{};
  32. template<> struct Log< 1 >
  33. {
  34. public:
  35.  Log(){}
  36.    ~Log()  {  log_buffer << std::endl;   }
  37.    std::ostringstream& Get(LogLevel level) const
  38.    {
  39.     log_buffer << GetTime() << " " << level << ": ";
  40.     return log_buffer;
  41.    }
  42. private:
  43.    Log(const Log& );
  44.    Log& operator =(const Log& );
  45. };
  46. ////////DO NOTHING//////////
  47. template<> struct Log< 0 >
  48. {
  49.  Log< 0 >& Get(LogLevel level)
  50.  {
  51.   return *this;
  52.  }
  53.  template<class T>
  54.  Log< 0 >& operator <<(T t)
  55.  {
  56.   return *this;
  57.  }
  58. };
  59. ////////WRITE TO FILE//////////
  60. template<> struct Log< 2 >
  61. {
  62.    void Get(LogLevel /*dummy*/) const
  63.    {
  64.      std::ofstream file(path);
  65.   file<< log_buffer.str();
  66.   file.close();
  67.    }
  68. };
  69. }


Message édité par Glock 17Pro le 03-06-2009 à 10:55:39
n°1890740
theshockwa​ve
I work at a firm named Koslow
Posté le 03-06-2009 à 11:14:21  profilanswer
 

pourquoi ne pas faire plutôt :

Code :
  1. WriteLog(DEBUG, "message" << i );
  2. WriteLog(CRITIQUE, "message2" );
  3. WriteLog(FLUSH);


 
et dans ta macro, tu ne fais rien, ou alors tu balance ton message dans ton stream ?


---------------
last.fm
n°1890746
Glock 17Pr​o
Posté le 03-06-2009 à 11:20:00  profilanswer
 

en testant avec un if dans la macro?

n°1890821
theshockwa​ve
I work at a firm named Koslow
Posté le 03-06-2009 à 13:35:52  profilanswer
 

Code :
  1. #define WriteLog_DEBUG( ... )
  2. #define WriteLog_CRITIQUE( message ) ostream << message;
  3. #define WriteLog( level, message ) WriteLog_##level( message )


 
en général, on passe par des macros pour le log aussi parce que ca permet facilement d'ajouter un __FILE__ et un __LINE__  pour avoir un meilleur suivi des problèmes, et ca permet de désactiver intégralement les logs via la définition d'une constante.
 
Sinon, tu dois aussi pouvoir faire un opérateur template du style :

Code :
  1. template<typename T>
  2. Log<0>& operator << ( Log<0>& log_stream, T& arg )
  3. {
  4.     return log_stream;
  5. }


 
Edit : précision : du coup, si tu fais ca pour le cas général et que tu rediriges directement vers ton stream que tu veux, ca te fera un petit overhead, mais pas bien méchant :o


Message édité par theshockwave le 03-06-2009 à 13:37:23

---------------
last.fm
n°1890829
Glock 17Pr​o
Posté le 03-06-2009 à 13:47:27  profilanswer
 

oui mais le problème c'est que le level pourlequel on veut filtré peut changer d'une execution à l'autre, là j'ai l'impression qu'avec ta macro, le code est figé, tous les messages de niveau égale à DEBUG sont filtrés, comment faire si je les veux par la suite, tout le temps changer à la main? pas très pratique

n°1890932
theshockwa​ve
I work at a firm named Koslow
Posté le 03-06-2009 à 14:56:41  profilanswer
 

mais dans ce cas, ton template ne pourra pas non plus s'en sortir ! Le choix du template sera nécessairement fait à la compilation.
 
Fais une interface de log de plus haut niveau. Tu envoies ton message à cet interface de log et elle fait une simple comparaison avec le niveau de log souhaité pour savoir si elle envoie dans le stream ou non et basta.
 
Je te conseille d'ailleurs, si tu veux quelque chose de puissant, de dissocier les appels aux logs de l'écriture dans les streams. Ca te permettra d'avoir, par exemple, plusieurs sorties de log différentes avec des configurations de verbosité différentes (genre, des logs à l'écran et dans un fichier, avec un niveau de détail plus élevé dans le fichier)


---------------
last.fm
n°1890954
Joel F
Real men use unique_ptr
Posté le 03-06-2009 à 15:20:42  profilanswer
 

et mates le proposal de Boost.Log aussi, y a pas mal d epb pas clair dans ce genre de tache.

n°1891022
Un Program​meur
Posté le 03-06-2009 à 16:15:50  profilanswer
 

J'ai déjà écrit une série de variations sur ce thème.  La structure que j'ai employée les dernières fois était une variation sur le thème:

Code :
  1. #define LOG  if(needToLog()) ; else getStream()


où LOG peut éventuellement avoir des paramètres passés tous ou en partie à needToLog() et getStream().

 

Le if();else est un bon vieux truc pour éviter de pairer un else qui suit la macro avec le if de la macro.

 

Si needToLog() est en fait constant, les compilateurs que j'ai testé vire le code mort mais continuent à détecter les erreurs de syntaxe -- ça évite les log qui ne compilent plus quand on les active parce que le dernier type qui a fait des modifs ne les utilise pas.  Ce peut naturellement être une variable (mise avec le débuggeur ou à l'initialisation avec une variable d'environnement) ou une fonction aussi compliquée que désiré.

 

getStream() renvoie soit un ostream& dans les versions les plus simples ou une classe avec un operator<< template forwardant vers un ostream interne (comme ça on peut avoir un format différent pour les logs et les IO textes normales) avec un constructeur et un destructeur qui ajoute ce qu'on désire (timestamp pour le ctor, flush pour le dtor sont les applications évidentes).

 

Le streambuf de l'ostream est ce que l'on veut.  C'est lui qui gère le choix des destinations (fichier, console, fenêtre modale ou non, ou combinaison)


Message édité par Un Programmeur le 03-06-2009 à 16:17:31

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  ça existe un ostream vide/bidon ?

 

Sujets relatifs
Executer une fonction quand on clique dans le videostream_iterator
count =>vide + selection sur 2 tablesVBS Tester si un dossier plus vieux de 7 jours existe et l'effacer
[RESOLU]html align bidon[VBS] Si Fichier existe...
[Resolu] Détecter lorsque l'utilisateur n'a rien rentré dans un input?Requête : un champs de plus si le premier est vide
Mon site existe en partie grâce à vous, merci !mysqldump via PHP -> fichier vide !
Plus de sujets relatifs à : ça existe un ostream vide/bidon ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR