Tout d'abord, nous savons que nous pouvons compter sur un coup de pouce.Préprocesseur pour notre boucle besoins. Toutefois, le code généré doit travailler sur son propre. Malheureusement, #ifdef
ne peut pas travailler en raison de l'expansion des macros, donc il n'y a aucun moyen de générer du code dans votre question. Sommes-nous grillées?
Pas encore! Nous pouvons tirer avantage du fait que vos macros sont soit inexistants, soit une chaîne littérale. Considérez les points suivants:
using StrPtr = char const *;
StrPtr probe(StrPtr(MACRO1));
Nous profitons de notre vieil ami, le plus grand d'analyser ici. La deuxième ligne peut être interprété de deux manières, selon que MACRO1
est défini. Sans elle, c'est équivalent à:
char const *probe(char const *MACRO1);
... qui est une déclaration de fonction où MACRO1
est le nom du paramètre. Mais, lorsqu' MACRO1
est "B"
, il devient équivalent à:
char const *probe = (char const *) "B";
... qui est une variable initialisée à point à l' "B"
. On peut ensuite passer sur le type de ce que nous venons de produit pour voir si une substitution s'est produite:
if(!std::is_function<decltype(probe)>::value)
std::cout << "MACRO1 " << probe << '\n';
Nous pourrions faire usage de l' if constexpr
ici, mais std::cout
pouvez sortie d'un pointeur de fonction (il convertit en bool
) de sorte que la branche morte est valide, et le compilateur est assez intelligent pour optimiser complètement hors.
Enfin, nous reviendrons à coup de fouet.Préprocesseur pour générer ce genre de choses pour nous:
#define PRINT_IF_DEFINED(z, n, data) \
{ \
StrPtr probe(StrPtr(BOOST_PP_CAT(MACRO, n))); \
if(!std::is_function<decltype(probe)>::value) \
std::cout << "MACRO" BOOST_PP_STRINGIZE(n) " " << probe << '\n'; \
}
#define PRINT_MACROS(num) \
do { \
using StrPtr = char const *; \
BOOST_PP_REPEAT(num, PRINT_IF_DEFINED, ~) \
} while(false)
... voilà!
Voir en direct sur Coliru
Remarque: le Coliru extrait comprend avertissement disablers pour GCC et Clang, qui mettent en garde contre notre pauvre pal la plus délicate à analyser :(