2010-02-03 8 views
3

Je pensais que d'une petite fonction en ligne de débogage en C++:C++ - En passant std :: ostream à une fonction

void inline debug(int debug_level, ostream& out) { 
    if (debug_level <= verbosity) { 
     out.flush(); 
    } 
    else { 
     ostream tmp; 
     tmp << out; 
    } 
} 

Ceci est un exemple de la façon dont je voulais l'utiliser:

_debug(7, cout << "Something something" << someint << endl); 

Cependant, cela ne fonctionne pas comme prévu - je voulais que le message soit imprimé uniquement si le niveau de verbosité est supérieur ou égal au niveau de débogage passé à fonctionner, mais il semble qu'il imprime à chaque fois quel que soit le niveau de débogage. dans le tampon cout. Maintenant, je pense que cette fonction n'est pas la meilleure idée que j'ai eu récemment, mais je veux quand même savoir s'il y a un moyen de vider le tampon associé à cout, cerr etc. Est-il possible de faire fonctionner correctement ce genre de fonction?

+0

Si vous voulez aller la route de Konrad, en utilisant l'idée d'un flux nul, jetez un oeil à cette question http://stackoverflow.com/questions/760301/implementing-a-no-op-stdostream –

+0

Oh, je Je n'aime pas les macros oldschool-C, je préfère la méthode C++;) – zbigh

+0

Les macros sont à peu près aussi évitables en C++ qu'en C, j'en ai peur. –

Répondre

2

Je ne suis pas sûr si cela peut être fait avec des fonctions/modèles. Je sais code avec macro de (votre journal message et le flux est séparé):

#define LOG(svrty, out, msg)\ 
do {\ 
    if (svrty >= debug_level) out << msg;\ 
} while(0) 

Bien que cela fonctionne, je suis intéressé par de meilleures solutions. Remarquez que vous devez laisser les paramètres de configuration et de débogage décider de l'endroit où se connecter.

2

Le message sera toujours imprimé car les paramètres de la fonction sont évalués avant que le corps de la fonction ne soit entré. Vous pouvez obtenir l'effet que je pense que vous voulez avec une macro, en tant que paramètres macro ne sont évalués quand ils sont utilisés:

#define DOUT(level, expr) \ 
    if (level >= verbosity) {  \ 
     expr << endl;   \ 
    } 

En utilisation:

DOUT(42, cout << "The value is " << something); 

Si vous êtes pointilleux, vous voulez enveloppez ceci dans une boucle do/while - personnellement, je ne m'en soucie jamais.

+0

@Neil: Eh bien, vous devriez vraiment * déranger * parce que maintenant votre utilisation est fausse: vous mettez un point-virgule redondant derrière. Ne pensez pas ce qui se passe si c'est dans un 'if' et l'instruction suivante est un' else'. –

+0

@Konrad Assez étonnamment, je sais cela. Considérez cela comme une de mes petites manies de codage. –

6

soit en utilisant une macro comme indiqué ci-dessus, ou comme ceci:

struct nullstream : ostream { 
    nullstream() : ostream(0) { } 
}; 

ostream& dout(int debug_level, ostream& out = cerr) { 
    static nullstream dummy; 
    return debug_level <= verbosity ? dummy : out; 
} 

// … 

dout(level) << "foo" << endl; 
dout(level, cout) << "IMPORTANT" << endl; 

(L'utilisation endl déclenche également le rinçage, pas besoin de rincer manuellement!)

+0

Seul le problème est la construction inutile d'un tampon de flux.Il est préférable d'éviter la construction du tampon de flux; Considérant que la journalisation peut être quelque chose que vous faites plus souvent que toute autre opération dans un processus sans tête. –

+0

@CodeMedic: c'est pourquoi le flux est 'static': il est construit seulement ** une fois **, dans tout le programme. C'est pratiquement pas de frais généraux et vous pouvez appeler cette méthode aussi souvent que vous le souhaitez. –

+0

@Konrad Rudolph: Cela a l'air cool, mais l'écriture constante sur un mannequin ne provoque-t-elle pas un débordement de tampon? – zbigh

0

Est-ce le configureable de temps d'exécution de niveau de débogage?
Sinon, vous pouvez utiliser des modèles et spécialisation du modèle:

template <int DebugLevel, int Verbosity> 
ostream &debug(ostream &out); 

template<> 
ostream &debug<7, 5>(ostream &out) { /* do stuff */ } 

De cette façon, si vous ne voulez pas quoi que ce soit de sortie, il suffit de retourner le mannequin ostream comme Konrad Rudolph suggéré.

Questions connexes