I am trying to use macro for calling appropriate object based on the type.
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.##FuncName(paramPtr); \
} \
else { \
return PolicyObject2.##FuncName(paramPtr); \
} \
return 0; \
(PolicyObject1 & PolicyObject2 are two static objects.) Now when using the macro, e.g.
DELEGATE_FUNC(ProcessPreCreate, 1, null_ptr);
It compiles fine in VS 2015, but gives error with LLVM "Pasting formed an invalid processing token '.ProcessPreCreate'"
I looked for, and found a few posts and understood it up to some level - Need double level of indirection, e.g. Why do I need double layer of indirection for macros?
However I am unable to define those two layers of macro, can anyone help?
(Please leave aside the discussion on design aspects)
Thanks
When the compiler reads your C++ file, one of the first steps is dividing it into tokens like identifier, string literal, number, punctuation, etc. The C preprocessor works on these tokens, not on text. The ##
operator glues tokens together. So, for example, if you have
#define triple(foo) foo##3
Then triple(x)
will get you the identifier x3
, triple(12)
will get you the integer 123
, and triple(.)
will get you the float .3
.
However, what you have is .##FuncName
, where FuncName
is ProcessPreCreate
. This creates the single token .ProcessPreCreate
, which is not a valid C++ token. If you had typed PolicyObject1.ProcessPreCreate
directly instead of through a macro, it would be tokenized into three tokens: PolicyObject1
, .
, and ProcessPreCreate
. This is what your macro needs to produce in order to give valid C++ output.
To do that, simply get rid of the ##
. It is unnecessary to glue the .
to the FuncName
, because they are separate tokens. To check this, you can put a space between a .
and a member name; it will still compile just fine. Since they are separate tokens, they should not and cannot be glued together.
delete "##".
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.FuncName(paramPtr); \
} \
else { \
return PolicyObject2.FuncName(paramPtr); \
} \
return 0; \
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With