ça existe un ostream vide/bidon ? - C++ - Programmation
Marsh Posté le 02-06-2009 à 08:56:00
non mais c'est assez simple à faire en héritant de stream je pense
Marsh Posté le 02-06-2009 à 12:10:08
il ferait qd mm tout son travail en interne. Tu fais un stream qui fait rien dans ses insertions/extractions et zou
Marsh Posté le 02-06-2009 à 12:16:44
Même si t'hérites, si tu veux tout transformer en NOP, il faudrait tout redéfinir inline
Marsh Posté le 02-06-2009 à 19:53:37
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
Marsh Posté le 03-06-2009 à 00:22:04
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
Marsh Posté le 03-06-2009 à 07:07:02
sauf que genre t'e as le 1er à y penser :E
quant à tes exigences sur le TR ....
Marsh Posté le 03-06-2009 à 10:31:06
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 ?
Marsh Posté le 03-06-2009 à 10:47:50
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 :
|
Marsh Posté le 03-06-2009 à 13:35:52
Code :
|
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 :
|
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
Marsh Posté le 03-06-2009 à 13:47:27
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
Marsh Posté le 03-06-2009 à 14:56:41
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)
Marsh Posté le 03-06-2009 à 15:20:42
et mates le proposal de Boost.Log aussi, y a pas mal d epb pas clair dans ce genre de tache.
Marsh Posté le 03-06-2009 à 16:15:50
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 :
|
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)
Marsh Posté le 02-06-2009 à 07:55:32
ç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