web-dev-qa-db-fra.com

Flux de sortie standard non opérationnel

Existe-t-il un moyen de créer une instance ostream qui, fondamentalement, ne fait rien?

Par exemple :

std::ostream dummyStream(...);
dummyStream << "Nothing will be printed";

Je pourrais simplement créer un flux ostring, mais les données seront mises en mémoire tampon (et je ne veux vraiment rien en faire, donc cela ajoute une surcharge inutile).

Une idée ?

[edit] J'ai trouvé cette question connexe qui convient à mes besoins. Cependant, je pense qu’il pourrait être utile de disposer d’une réponse indiquant comment créer un flux de sortie valide (sans badbit) avec le c ++ standard.

35
Maël Nison

Vous avez besoin d'un streambuf personnalisé. 

class NullBuffer : public std::streambuf
{
public:
  int overflow(int c) { return c; }
};

Vous pouvez ensuite utiliser ce tampon dans n’importe quelle classe ostream

NullBuffer null_buffer;
std::ostream null_stream(&null_buffer);
null_stream << "Nothing will be printed";

streambuf::overflow est la fonction appelée lorsque le tampon doit émettre des données vers la destination réelle du flux. La classe NullBuffer ci-dessus ne fait rien lorsque le dépassement de capacité est appelé, de sorte que tout flux l'utilisant ne produira aucune sortie.

58
john

S'il s'agit de désactiver la sortie de la journalisation, votre dummyStream provoquera toujours l'évaluation des arguments. Si vous souhaitez minimiser l'impact lorsque la journalisation est désactivée, vous pouvez vous fier à une condition, telle que:

#define debugStream \
    if (debug_disabled) {} \
    else std::cerr

Donc, si vous avez un code comme:

debugStream << "debugging output: " << foo() << std::endl;

Aucun argument ne sera évalué si debug_disabled est vrai.

27
jxh

La méthode de base pour les nouvelles classes de flux est la suivante:

  1. Dérivez une classe de std::streambuf;
  2. Remplacez les fonctions virtuelles dans cette classe. C'est là que le vrai travail est fait. Dans votre cas, les implémentations vides devraient suffire.
  3. Dérivez une classe de std::ostream avec un membre, votre classe streambuf.
  4. Le constructeur de votre classe de flux doit transmettre le pointeur à ce membre vers le constructeur de base de std :: ostream.

J'ai bien peur que vous ne vous débarrassiez pas de l'étape de formatage.

J'espère que cela vous donne des indications; Je n'ai pas le temps d'élargir cela en réponse complète, désolé.

Update : voir réponse de john pour plus de détails.

3
Sjoerd

Si vous êtes préoccupé par la surcharge de votre débogueur, vous pouvez écrire un code très simple pour annuler vos messages de débogage lors de la compilation. C'est ce que j'utilise pour mes programmes c ++.

#include <iostream>
#define DEBUGGING // Define this in your config.h or not.
#ifdef DEBUGGING
/*
 * replace std::cout with your stream , you don't need to
 * worry about the context since macros are simply search
 * and replace on compilation.
 */
#define LOG_START std::cout <<
#define LOG_REDIR <<
#define LOG_END   << std::endl;
#else
#define LOG_START (void)
#define LOG_REDIR ;(void)
#define LOG_END   ;
#endif // DEBUGGING

int main(){
LOG_START "This is a log message " LOG_REDIR "Still a log message." LOG_END;
return 0;
}

Maintenant, lors de la création de votre projet, vérifiez si l'utilisateur souhaite désactiver la journalisation. Si tel est le cas, indiquez simplement la macro DEBUGGING ou la macro que vous souhaitez vérifier.

Maintenant, votre code sera optimisé par le compilateur. Parce que lorsque quelque chose est annulé, il ne sera pas inclus dans le binaire résultant (la plupart du temps), ce qui rendra la production binaire prête.

0
antonyjr