我有一个宏,其中一个参数是一个枚举值,在没有指定命名空间范围的情况下给出。但是在宏内部我需要访问它(显然我必须在那里定义命名空间),但我似乎无法使用模板参数连接命名空间名称。给定以下示例代码,编译器会抱怨pasting :: and Val doesnt give a valid preprocessor token
(它可以很好地将get和a连接到getVal)。
namespace TN
{
enum Info
{
Val = 0
};
}
#define TEST(a) TN::Info get ## a(){return TN::##a;}
TEST(Val)
那么有没有办法让这项工作不使用另一个参数并基本上指定要使用两次的值(例如#define TEST(a,b) TN::Info get ## a(){return b;}
)?
答案 0 :(得分:10)
##
是一个令牌粘贴运算符,即它应该从多个令牌中生成一个令牌,正如编译器所说,::Val
不是单个令牌,它是两个令牌。 / p>
为什么你需要认为你需要第二个##
?这有什么不对。
#define TEST(a) TN::Info get ## a () { return TN::a; }
答案 1 :(得分:3)
如果要连接两个项目并让编译器将结果视为单个标记(例如标识符),则仅使用##。
在你的宏中,第一次使用##是正确的,因为你试图通过粘贴get
和a
的内容来构造一个标识符,但第二次使用##是假的,因为你只想从a
的内容中创建一个标识符,而::运算符是一个独立的实体。海湾合作委员会会抱怨这一点(尽管MSVC ++应对)。
#define TEST(a) TN::Info get ## a(){return TN::a;}
应该有用。