2017-09-24 2 views
0

Le but ici est d'obtenir simplement a, b, c au lieu de leurs valeurs réelles. La configuration est « assez simple »:empêchant la ré-expansion de macros inattendue avec boost?

#include <boost/preprocessor/seq/for_each_i.hpp> 
#include <boost/preprocessor/seq/for_each.hpp> 
#include <boost/preprocessor/stringize.hpp> 
#include <iostream> 

// Define "invalid" sequence first 
#define SEQ (a)(b)(c) 

// Try to create "final" value with `std::string("elem")` 
// Brought in for explicit `std::string`, but no dice 
#define MAKE_XSTRING(x) MAKE_STRING(x) 
#define MAKE_STRING(x) std::string(#x) 

// oh, the humanity!    vvvvvvvvvvvv or BOOST_PP_STRINGIZE 
#define HUMANIZE(r, data, elem) (MAKE_XSTRING(elem)) 
#define SEQ_HUMAN BOOST_PP_SEQ_FOR_EACH(HUMANIZE,,SEQ) 

Alors que je me attends à ce moment est ce que j'ai: une nouvelle séquence avec (std::string("a")) etc:

// confirmation:  vvvvvvvvvvvvvvvv 
// warning: Humans: (std::string("a")) (std::string("b")) (std::string("c")) 
#pragma message "Humans: " BOOST_PP_STRINGIZE(SEQ_HUMAN) 

pensant que je suis très intelligent et j'ai obtenu mes valeurs triées dans des chaînes explicites, maintenant je définis les valeurs réelles pour ce que le «vrai» code a besoin.

// Now that we have the "final" values, actually define the real values 
// in real code, it's some lengthy nested namespaces (inconvenient to type) 
#define a 123 
#define b 456 
#define c 789 

Et enfin, permet de les imprimer pour vous assurer qu'ils ne sont pas développés:

// Let there be printing! 
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << elem << std::endl 

int main(int argc, const char **argv) { 
    std::cout << "Humans: " << std::endl 
     BOOST_PP_SEQ_FOR_EACH_I(GOTTA_PRINT_EM_ALL,,SEQ_HUMAN); 
} 

Mais il semble que les étrangers ont en effet prendre en charge:

Humans: 
1. 123 
2. 456 
3. 789 

Étant donné que ils sont censés être std::string("a") ... comment diable sont les vraies valeurs qui y retournent ?! J'ai pensé que peut-être le ("a") du constructeur std::string a créé des problèmes, mais il ne semble pas ainsi (BOOST_PP_STRINGIZE résultats dans le même comportement). Aucune suggestion?

Répondre

1

La macro se développe en effet dans Code jetons:

test.cpp|24 col 1| note: #pragma message: Humans: (std::string("123")) (std::string("456")) (std::string("789")) 

Maintenant lorsque vous insérez le code jetons dans votre GOTTA_PRINT_EM_ALL macro, vous obtenez

<< ((0)+1) << ". " << std::string(\"123\") << std::endl << ((1)+1) << ". " << std::string(\"456\") << std::endl << ((2)+1) << ". << std::string(\"789\")" << std::endl 

complètement l'impression expectedly

Humans: 
1. 123 
2. 456 
3. 789 

Pour obtenir le vous avez besoin "code de jetons" pour stringize eux aussi:

// Let there be printing! 
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << BOOST_PP_STRINGIZE(elem) << std::endl 

Impression

Humans: 
1. std::string("123") 
2. std::string("456") 
3. std::string("789") 

Voir ce Live On Coliru

#include <boost/preprocessor/seq/for_each_i.hpp> 
#include <boost/preprocessor/seq/for_each.hpp> 
#include <boost/preprocessor/stringize.hpp> 
#include <iostream> 
#include <string> 

#define a 123 
#define b 456 
#define c 789 
#define SEQ (a)(b)(c) 

// Try to create "final" value with `std::string("elem")` 
// Brought in for explicit `std::string`, but no dice 
#define MAKE_STRING(x) std::string(#x) 
#define MAKE_XSTRING(x) MAKE_STRING(x) 

#define HUMANIZE(r, data, elem) (MAKE_XSTRING(elem)) 
#define SEQ_HUMAN BOOST_PP_SEQ_FOR_EACH(HUMANIZE,,SEQ) 

// Let there be printing! 
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << BOOST_PP_STRINGIZE(elem) << std::endl 

int main() { 
    std::cout << "Humans: " << std::endl 
     BOOST_PP_SEQ_FOR_EACH_I(GOTTA_PRINT_EM_ALL,,SEQ_HUMAN); 
} 
+0

Je me rends compte maintenant ce n'est pas ce que vous vouliez demander. Je vais laisser cette "réponse" ici un peu pour que vous puissiez CLARIFIER la question. Je comprends maintenant, mais ce n'est pas du tout très clair. Créez un exemple de programme _self-contained_ qui ne laisse rien à l'interprétation. – sehe

+0

En utilisant la réponse de la question en double lié: http://coliru.stacked-crooked.com/a/5405ce9f8218092f – sehe

+0

Salut @sehe merci de l'expliquer et de me relier à la question que je n'ai pas pu trouver. Tout cela a beaucoup plus de sens maintenant, je suppose que je ne me suis pas vraiment rendu compte que les citations sont échappées jusqu'à leur utilisation – sjm324