【问题标题】:How to use macro arguments in call to another macro?如何在调用另一个宏时使用宏参数?
【发布时间】:2016-02-11 21:46:05
【问题描述】:

我希望能够创建一个调用其他宏的宏。我要调用的宏是来自follyBenchmark 宏。

最后,我想要一堆看起来像这样的宏:

BENCHMARK(filter_10_vector_1_filter, n) { ... }
BENCHMARK(filter_10_set_1_filter, n) { ... }
BENCHMARK(filter_10_vector_2_filter, n) { ... }
BENCHMARK(filter_10_set_2_filter, n) { ... }
BENCHMARK(filter_10_vector_3_filter, n) { ... }
BENCHMARK(filter_10_set_3_filter, n) { ... }
... all the way to 10_filter

BENCHMARK(filter_100_vector_1_filter, n) { ... }
BENCHMARK(filter_100_set_1_filter, n) { ... }
... all the way to 10_filter

我尝试创建一个如下所示的宏:

#define CreateBenchmark(numElements, numFilters) \
  BENCHMARK(filter_##numElements_vector_##numFilters_filters, n) { ... } \
  BENCHMARK_RELATIVE(filter_##numElements_set_##numFilters_filters, n) { ... }

CreateBenchmark(10, 2);

这有望将我需要编写的宏数量减半。然而,##numElements##numFilters 的替换并没有像我希望的那样发生。 CreateBenchmark(10, 2) 调用的结果是

============================================================================
FilterWithSetBenchmark.cpp  relative  time/iter  iters/s
============================================================================
filter_numElements_vector_numFilters_filters               264.35us    3.78K
filter_numElements_set_numFilters_filters         99.93%   264.54us    3.78K
============================================================================

我期待filter_10_vector_2_filtersfitler_10_set_2_filters。有没有办法将提供给CreateBenchmark 宏的值分到传递给BENCHMARKBENCHMARK_RELATIVE 调用的值中?

作为奖励,我的 CreateBenchmark 宏能否使用 for 循环来创建所有 XX_filters,以便对 CreateBenchmark 的一次调用生成 20 个宏调用(_vector_ 为 10 个,_set_ 为 10 个) ?

【问题讨论】:

  • 感谢您展示了我见过的## 的第一个合理用法。您是否会使用三元组?
  • 没问题,我猜? :p 你通常会在什么情况下看到## 使用?不,我不使用三元组,只是编写一些常规的基准测试-使用-a-set-instead 代码。
  • 我认为我没有在完全人为的例子之外看到##。这就是我对三元组的看法。
  • 有趣。这是我第一次编写 C++ 宏,但在学习的过程中,我浏览了一些我们依赖的库(忘记了哪些),并在那里看到了一些示例。
  • 我对 C++ 做的不多,但我预计它会比纯 C 更多地出现在纯粹的数量上。如果我记得的话,像 boost 和 gtest 这样的东西是相当宏观的,增加了像 ## 这样的东西以一种有意义的方式出现的机会。

标签: c++ macros


【解决方案1】:

您忘记了尾随连接运算符##

#define CreateBenchmark(numElements, numFilters) \
  BENCHMARK(filter_ ## numElements ## _vector_ ## numFilters ## _filters, n) { ... } \
  BENCHMARK_RELATIVE(filter_ ## numElements ## _set_ ## numFilters ## _filters, n) { ... }

## 视为字符串连接运算符,就像Java 或Python 中的+

【讨论】:

    【解决方案2】:

    偶然发现。我的创建宏功能需要更多#。这是新的:

    #define CreateBenchmark(numElements, numFilters) \
      BENCHMARK(filter_##numElements##_vector_##numFilters##_filters, n) { ... } \
      BENCHMARK_RELATIVE(filter_##numElements##_set_##numFilters##_filters, n) { ... }
    

    基本上,我想要替换的内容需要完全包含在双 # 中。从##numElements 转到##numElements##numFilters 也是如此。

    【讨论】:

      【解决方案3】:

      您可以使用__VA_ARGS__ 来表示宏参数。

      【讨论】:

      • 这将如何远程适用于 OP 的情况?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 2019-01-28
      相关资源
      最近更新 更多