gpt4 book ai didi

c++ - 可变宏警告

转载 作者:太空宇宙 更新时间:2023-11-04 15:13:39 25 4
gpt4 key购买 nike

在 C++ 中,可变参数宏至少需要一个参数来表示“...”。考虑函数:FOO(a, b, ...); 如果我希望这两个调用都正确且没有警告,我应该怎么做? FOO(5, 4, " Gamma "); FOO(5, 4); 我正在使用 --pedantic 标志,所以只抑制警告不是一个选项。

第二个给出了上面提到的编译时警告。我考虑过这个:

将定义更改为 FOO(a, ...); 并将 __VA_ARGS__ 变量(代表 ...)拆分为 b,如果存在,进入其余部分。所以函数调用看起来像:FOO(5, "4gamma");FOO(5, "4"); 我认为这不是一个好的选项,因为拆分效率不高,函数声明不需要 b 参数,即使它是强制性的。

有没有更好的方法来获得无警告的编译?

最佳答案

虽然我完全同意如果可能的话,应该使用可变参数函数或函数模板,这个问题也显示出一些关于宏可以做什么和不能做什么的误解,所以在这个答案中我会假装函数是不是一个选择。

Changing the definition to FOO(a, ...); and splitting the __VA_ARGS__ variable (which stands for ...) into b and, if present, into the rest.

是的。

So the function calls would look like: FOO(5, "4gamma"); and FOO(5, "4");

没有。继续调用 FOO(5, 4, "gamma");FOO(5, 4);。在第一种情况下,__VA_ARGS__4, "gamma"。在第二种情况下,__VA_ARGS__4

如果您需要从前者中提取, "gamma",这可以由预处理器完成。它需要参数数量的上限,但您可以将其增加到几乎任何您喜欢的数量。虽然很丑。

如果 __VA_ARGS__ 不包含逗号,则提取很简单:

#define COMMA_TRAILING_ARGS_0(a)

如果您知道 __VA_ARGS__ 包含至少一个逗号,您可以使用

#define COMMA_TRAILING_ARGS_1(a, ...) , __VA_ARGS__

并且您可以检测使用其中的哪些,直到达到宏参数的某个上限:

#define ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) _16
#define HAS_COMMA(...) ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, )

合并:

#define COMMA_TRAILING_ARGS_0(a)
#define COMMA_TRAILING_ARGS_1(a, ...) , __VA_ARGS__

#define ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) _16
#define HAS_COMMA(...) ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,)

#define CONCAT(a, b) a ## b
#define CONCAT_(a, b) CONCAT(a, b)

#define FOO(a, ...) BAR(a CONCAT_(COMMA_TRAILING_ARGS_, HAS_COMMA(__VA_ARGS__)) (__VA_ARGS__))

FOO(5, 4, x, q); // expands to BAR(5, x, q);
FOO(5, 4, "gamma"); // expands to BAR(5, "gamma");
FOO(5, 4); // expands to BAR(5);

关于c++ - 可变宏警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43435497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com