【问题标题】:Count number of variadic arguments in macro function计算宏函数中可变参数的数量
【发布时间】:2018-12-19 08:27:36
【问题描述】:

这是我在 OpenCV 中看到的两行代码

#define CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...)    N
#define CV_VA_NUM_ARGS(...)      CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

我猜是计算传递给CV_VA_NUM_ARGS 的可变参数的数量。以如下代码为例:

CV_VA_NUM_ARGS(a,b,c)

将扩展到

CV_VA_NUM_ARGS_HELPER(a,b,c,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

在这一点上,我一直在理解发生了什么。具体来说,我不知道_1、_2等的用处。有人可以帮帮我吗?这是一个类似的post,但对我来说更复杂。

编辑: 当我不传递任何参数时(比如CV_VA_NUM_ARGS_HELPER()),宏将被替换为 1 而不是 0,这是为什么呢?

【问题讨论】:

  • 顺便说一句,如果你想计算超过 10 个可变参数的数量,#define CV_VA_NUM_ARGS(...) std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value 在 C++11 中有效。
  • @Hiroki:一般情况下,会根据参数数量在其他 MACRO 上进行调度,所以这种方式“失败”
  • @Jarod42 thx 但我仍然不太了解您的评论。假设such use cases,我评论了上面的行。那么你的“失败”是什么意思?因为通过我这 2 个月的 SO 生活,我知道您是一名出色的 C++ 程序员,所以我想通过示例准确理解您所说的内容并向您学习:)。
  • @Hiroki:我的意思是像example一样遍历可变参数宏,
  • @Jarod42 啊,我明白了。非常感谢!

标签: c++ c macros


【解决方案1】:

_1 到 _10 从一开始就只是占位符,以确保 N 位于从 10 到 0 的正确数字上(取决于 __VA_ARGS__)。除了占据一个职位之外,他们没有其他任何目的。

由于每个宏参数都必须有一个不同的标识符,因此这些标识符与任何标识符一样好。


关于您的编辑,这是预处理器的限制。空标记序列是宏的有效参数。所以它确实是一个参数,因为__VA_ARGS__ ,(注意逗号)变成了这样一个参数。

这是一个众所周知的问题,以至于 C++20 添加了 __VA_OPT__ 预处理器宏。它允许有条件地添加逗号。在 C++20 上,可以像这样修复实现以按预期工作:

#define CV_VA_NUM_ARGS(...)      CV_VA_NUM_ARGS_HELPER(__VA_ARGS__ __VA_OPT__(,) 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

【讨论】:

    【解决方案2】:

    _1、_2 等没有什么特别之处。你可以用i、j、k 代替它们。

    N 的值取决于您传递的参数数量,因为 N 成为宏扩展中的第 11 个元素(因为有 10 个占位符)。

    所以对于CV_VA_NUM_ARGS(a,b,c),第 11 个元素是 3。 对于CV_VA_NUM_ARGS(a,b,c,d,e,f),第 11 个元素是 6,以此类推。

    请注意,使用此特定代码,您最多只能计算 10 个参数。使用超过 10 个参数会产生编译器错误。

    【讨论】:

      猜你喜欢
      • 2014-10-01
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-13
      • 1970-01-01
      • 2014-06-07
      相关资源
      最近更新 更多