tags:

views:

98

answers:

2

I have a macro, where one of the arguments is an enum value, which is given without specifying the namespace scope. However somewhere inside the macro I need to access it (obviously I must define the namespace there), but I can't seem to concat the namespace name with the template parameter. Given the following samplecode the compiler complains that pasting :: and Val doesnt give a valid preprocessor token (it works fine for concating get and a to getVal though).

 namespace TN
 {
    enum Info
    {
        Val = 0
    };
 }

#define TEST(a) TN::Info get ## a(){return TN::##a;}
TEST(Val)

So is there any way to make this work without using another argument and basically specifying the value to be used twice (e.g. #define TEST(a,b) TN::Info get ## a(){return b;})?

+2  A: 

Only use ## when you want to concatenate two items and have the compiler treat the result as a single token (e.g. an identifier).

In your macro, the first use of ## is correct, as you are trying to construct an identifier by pasting together get and the contents of a, but second use of ## is spurious, as you just want to make an identifier out of the contents of a and the :: operator is a separate entity to that. GCC will complain about this (though MSVC++ copes).

#define TEST(a) TN::Info get ## a(){return TN::a;}

should work.

moonshadow
+2  A: 

## is a token pasting operator, i.e. it should make a single token out of multiple bits of token and as the compiler says, ::Val isn't a single token, it's two tokens.

Why do you need think you need the second ## at all? What's wrong with this.

#define TEST(a) TN::Info get ## a () { return TN::a; }
Charles Bailey
obviously I'm thinking way to complex, thanks
Grizzly