3

Étant donné un entier constant à la compilation (un objet, pas une macro), puis-je le combiner avec un littéral de chaîne au moment de la compilation, éventuellement avec le préprocesseur?Combinaison de littéraux de chaîne et de constantes entières

Par exemple, je peux concaténer des chaînes littérales simplement en les plaçant côte à côte:

bool do_stuff(std::string s); 
//... 
do_stuff("This error code is ridiculously long so I am going to split it onto " 
     "two lines!"); 

Great! Mais si j'ajouter des constantes entières dans le mélange:

const unsigned int BAD_EOF = 1; 
const unsigned int BAD_FORMAT = 2; 
const unsigned int FILE_END = 3; 

Est-il possible d'utiliser le préprocesseur pour concaténer en quelque sorte cela avec les littéraux de chaîne?

do_stuff("My error code is #" BAD_EOF "! I encountered an unexpected EOF!\n" 
     "This error code is ridiculously long so I am going to split it onto " 
     "three lines!"); 

Si ce n'est pas possible, est-ce que je peux mélanger des chaînes constantes avec des chaînes littérales? C'est à dire. si mes codes d'erreur étaient des chaînes, au lieu de non-signés?

Et si ce n'est pas possible, quel est le moyen le plus court et le plus propre de regrouper ce mélange de chaînes littérales et de codes d'erreur numériques?

Répondre

9

Si BAD_EOF était une macro, vous pouvez stringize il:

#define STRINGIZE_DETAIL_(v) #v 
#define STRINGIZE(v) STRINGIZE_DETAIL_(v) 

"My error code is #" STRINGIZE(BAD_EOF) "!" 

Mais ce n'est pas (et qui est à peu près toujours une bonne chose), donc vous devez formatthestring:

stringf("My error code is #%d!", BAD_EOF) 

stringstream ss; ss << "My error code is #" << BAD_EOF << "!"; 
ss.str() 

Si cela vous préoccupait énormément (il ne devrait pas l'être, certainement pas au début), utilisez une chaîne séparée et spécialisée pour chaque constante:

unsigned const BAD_EOF = 1; 
#define BAD_EOF_STR "1" 

Cela a tous les inconvénients d'une macro plus plus à screwup maintenir pour un peu de performance que probablement won't matter pour la plupart des applications. Cependant, si vous décidez de ce compromis, il doit s'agir d'une macro car le préprocesseur ne peut pas accéder aux valeurs , même s'il s'agit de const.

+0

Ah, oui. Cette double macro est importante. Quelque chose que j'ai oublié dans mon exemple. Bon spectacle. – JoshD

+0

pourquoi la double macro? – Chubsdad

+3

@ Chubsdad: http://codepad.org/DiAC35hl –

1

Quel est le problème avec:

do_stuff(my_int_1, 
    my_int_2, 
    "My error code is #1 ! I encountered an unexpected EOF!\n" 
    "This error code is ridiculously long so I am going to split it onto " 
    "three lines!"); 

Si vous voulez abstraire les codes d'erreur, vous pouvez le faire:

#define BAD_EOF "1" 

vous pouvez utiliser BAD_EOF comme si elle était une chaîne littérale.

+1

Hmm. Cela pourrait casser beaucoup de code si ce #define était utilisé comme un type intégral – Chubsdad