C++宏文本操作

发布于 2024-10-14 23:26:51 字数 268 浏览 3 评论 0原文

我想编写一个带有任意参数的 C++ 宏,例如:

#define MANIP(...) \ 
//Implementation

这样编写

MANIP(m_a, m_b, m_c);

扩展为

f(a, b, c);
g("a", "b", "c");

这可能吗?

预先感谢您帮助我解决这个看似奢侈的问题:)

I would like to write a C++ macro taking arbitrary argument like:

#define MANIP(...) \ 
//Implementation

Such that writing

MANIP(m_a, m_b, m_c);

expands to

f(a, b, c);
g("a", "b", "c");

Is this possible?

Thank you in advance for helping me with this seemingly extravagant question :)

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

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

发布评论

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

评论(3

梦中的蝴蝶 2024-10-21 23:26:51

我不相信有一种简单的方法可以从 m_a 转到 a。但是,字符串化运算符 # 是标准 C 和 C++ 的一部分。

例如,给定

#define STRING(x) #x

STRING(m_a) 将转换为 "m_a"

I don't believe there will be an easy way to go from m_a to a. However, the stringize operator # is part of standard C and C++.

for example, given

#define STRING(x) #x

then STRING(m_a) will be transformed to "m_a".

赤濁 2024-10-21 23:26:51

预处理器无法分割标记。这意味着不可能从 m_foo 生成 foo 或(正如最近询问的那样)从 "foo" 生成 foo >。

如果您可以使用可变宏(正如 Matthieu M. 指出的,这意味着 C99 或 C++0x)Jens Gustedt 的 P99 库 在这里会很有帮助。有一些宏可以使这变得更加容易,但是让我们让不熟悉该库的人也可以阅读它,好吗?

简化情况:传递两个或三个参数。

#define MANIP2(a, b) \
    f(a, b)          \
    g(#a, #b)

#define MANIP3(a, b, c) \
    f(a, b, c)          \
    g(#a, #b, #c)

#define MANIP(...)   \
    MANIP_(          \
        P99_PASTE2(MANIP, P99_NARG(__VA_ARGS__)), \
        __VA_ARGS__) \

#define MANIP_(MANIPMAC, ...) MANIPMAC(__VA_ARGS__)

这说明了基本原理。在实践中,有 foreach 风格的宏(类似于 Boost 的宏)可以使编码更容易(尽管,正如我提到的,对于新手来说更难阅读)。请参阅 P99 库文档细节。

The preprocessor cannot split tokens. This means it is impossible to produce foo from m_foo or (as has recently been asked) foo from "foo".

If you can use variadic macros (as Matthieu M. points out, this means C99 or C++0x) Jens Gustedt’s P99 library would be helpful here. There are macros to make this even easier, but let’s make this readable to people who aren’t familiar with the library, OK?

Simplified case: there are either two or three arguments passed.

#define MANIP2(a, b) \
    f(a, b)          \
    g(#a, #b)

#define MANIP3(a, b, c) \
    f(a, b, c)          \
    g(#a, #b, #c)

#define MANIP(...)   \
    MANIP_(          \
        P99_PASTE2(MANIP, P99_NARG(__VA_ARGS__)), \
        __VA_ARGS__) \

#define MANIP_(MANIPMAC, ...) MANIPMAC(__VA_ARGS__)

This illustrates the basic principle. In practice, there are foreach-style macros (analogous to Boost’s) to make this easier to code (though, as I mentioned, harder to read for the uninitiated). See the P99 library documentation for details.

云仙小弟 2024-10-21 23:26:51

让预处理器(它处理#define 语句,而不是 C++ 编译器本身)将参数分成几部分实际上是不可能的。因此,如果您尝试从 m_a 中提取 a,则无法执行此操作。相反,最好将宏定义为:

  #define MANIP(m, a, b, c)

并要求“m”是单独的输入。

其次,您无法轻松地将非字符串输入转换为字符串输入。 IE,从 a 转换为 "a" 并不容易。我这样表述是因为我知道一些 CPP(C 预处理器)可以做到这一点。但我不认为它是便携式的。

一般来说,当您尝试做复杂的事情时,您应该使用编程语言而不是 CPP。

具体来说,在 C++ 中,您拥有的模板可以让您比 CPP 的 #define 语句走得更远。

It's not really possible to have the pre-processor (which is what handles #define statements, not the C++ compiler itself) break arguments into parts. So if you're trying to extract the a from m_a you can't do it. Instead it'd be better to define your macro like:

  #define MANIP(m, a, b, c)

And require the 'm' to be a separate input.

Secondly, you can't easily convert from non-string inputs to string inputs. IE, converting from a to "a" isn't easily doable. I'm phrasing it that way since I know some CPPs (C-Pre-processor) can do it. But I don't think it's portable.

Generally when you're trying to do complex things, you should be working with the programming language rather than the CPP.

Specifically, in C++ you have templates which will let you get a lot farther with work like that than #define statements for the CPP.

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