将宏参数与命名空间连接起来

发布于 2024-08-15 22:22:32 字数 470 浏览 2 评论 0原文

我有一个宏,其中参数之一是枚举值,该值是在未指定命名空间范围的情况下给出的。然而,在宏内部的某个地方,我需要访问它(显然我必须在那里定义名称空间),但我似乎无法将名称空间名称与模板参数连接起来。给出以下示例代码,编译器抱怨粘贴 :: 和 Val 没有给出有效的预处理器标记(尽管它对于连接 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;} )?

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;})?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡の花香 2024-08-22 22:22:32

## 是一个标记粘贴运算符,即它应该从多个标记位中生成单个标记,并且正如编译器所说,::Val 不是单个标记,这是两个令牌。

为什么你认为你需要第二个 ## ?这有什么问题呢。

#define TEST(a) TN::Info get ## a () { return TN::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; }
平生欢 2024-08-22 22:22:32

仅当您想要连接两个项目并使编译器将结果视为单个标记(例如标识符)时才使用##。

在您的宏中,第一次使用 ## 是正确的,因为您尝试通过将 geta 的内容粘贴在一起来构造标识符,但第二次使用 # # 是虚假的,因为您只想从 a 的内容中创建一个标识符,而 :: 运算符是一个独立的实体。 GCC 会抱怨这一点(尽管 MSVC++ 可以应对)。

#define TEST(a) TN::Info get ## a(){return TN::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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文