宏中的波浪号(〜)是什么意思?

时间:2011-06-25 15:44:42

标签: c++ c c-preprocessor tilde

this site上看到,代码显示了在括号中使用波浪号的宏调用:

HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
//                                          ^^^

这是什么意思/做什么?我怀疑它只是一个空洞的争论,但我不确定。它是否特定于C(99),如__VA_ARGS__特定于C99并且存在于C ++中?

3 个答案:

答案 0 :(得分:30)

在Boost.Preprocessor的介绍页面上,在 A.4.1.1水平重复

中给出了一个例子。
#define TINY_print(z, n, data) data

#define TINY_size(z, n, unused)                                 \
  template <BOOST_PP_ENUM_PARAMS(n, class T)>                   \
  struct tiny_size<                                             \
      BOOST_PP_ENUM_PARAMS(n,T)                                 \
      BOOST_PP_COMMA_IF(n)                                      \
      BOOST_PP_ENUM(                                            \
          BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none)      \
  >                                                             \
    : mpl::int_<n> {};

BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~) // Oh! a tilde!

#undef TINY_size
#undef TINY_print

下面提供了解释:

  

代码生成过程通过调用BOOST_PP_REPEAT开始,这是一个高阶宏,它反复调用由其第二个参数(TINY_size)命名的宏。第一个参数指定重复调用的次数,第三个参数可以是任何数据;它被传递给未被调用的宏。 在这种情况下,TINY_size不使用该数据,因此传递~的选择是任意的。 [5]

(强调我的)

还有注释:

  

[5] ~并非完全武断的选择。 @$都可能是不错的选择,除了技术上它们不是C ++实现需要支持的基本字符集的一部分。像被忽略的标识符可能会受到宏扩展的影响,从而导致意外结果。

因此,波浪号只是一个占位符,因为需要参数,但没有必要。由于任何用户定义的标识符都可以扩展,因此您需要使用其他内容。

事实证明,与~+相比,-几乎未被使用(二进制否定通常不被称为),因此几乎没有混淆的可能性。一旦你确定了这一点,使用它一直给它一个 new 意义到代字号;比如使用operator<<operator>>来传输数据已成为C ++的习惯用语。

答案 1 :(得分:4)

~什么也没做。这些括号内的几乎任何其他内容都可以正常工作。

这个技巧的关键是测试_TRIGGER_PARENTHESIS_扩展中(~)是否在_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)旁边。无论哪种方式,HAS_COMMA(...)都会将其参数扩展为01

答案 2 :(得分:3)

要测试的参数放在宏和它的括号之间,宏只在参数为空时触发:

_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)

注意:实际上您发布的链接指出了它。我将在标准中检查对此的参考。