J'ai un objet shared_ptr x, qui a les méthodes get et set comme suit:
x->a_value();
x->set_a_value();
x->b_value();
x->set_b_value();
Quand j'essaie de définir une macro:
#define MAC(type) \
x->set_##type##_value(val);
MAC(a)
Cela fonctionne bien, mais quand je le fais:
#define MAC(type) \
x->##type##_value();
MAC(a)
cela donne l'erreur de compilation suivante: pasting formed '->a', an invalid preprocessing token
Le préprocesseur fonctionne sur des "jetons" - aime les noms et les opérateurs.
L'opérateur ##
crée un nouveau jeton en collant des pièces plus petites. Dans le premier exemple, set_##type##_value
devient set_a_value
, qui est un jeton valide.
Dans le deuxième exemple, ->##type##_value
deviendrait ->a_value
, ce qui représente pas un jeton de préprocesseur valide. Il devrait y avoir deux jetons.
Si vous faites juste la ligne x->type##_value();
cela devrait marcher. Vous obtenez les jetons distincts x
, ->
, a_value
, (
, )
et ;
.
Ce qui est écrit sur l'étain: ->a
n'est pas un seul jeton valide de préprocesseur: c'est deux jetons. Vous n'avez pas besoin de coller ici.
#define MAC(type) \
x->type##_value();
L'opérateur de collage de jetons (##
) est utilisé pour concaténer deux jetons en un seul jeton valid.
Quand tu écris
x->##type##_value();
Le premier jeton traité est x
.
Le jeton suivant est formé en concaténant le jeton ->
avec type
, puisque type
est a
, le résultat de la concaténation est ->a
, qui doit être un jeton valide, mais ne le est pas.
Par conséquent, vous obtenez l'erreur: pasting formed '->a', an invalid preprocessing token
.
Pour résoudre ce problème, il suffit d'écrire
x->type##_value();
Par ici
Le premier jeton analysé est x
.
Le prochain jeton analysé est ->
.
Le jeton suivant est formé en concaténant le jeton type
(qui devient a
) avec le jeton _value
. Cela donne a_value
, qui est un jeton valide.
Le prochain jeton est (
.
Le prochain jeton est )
.
Le dernier jeton est ;
.