宏中的波浪号 (~) 是啥意思?
Posted
技术标签:
【中文标题】宏中的波浪号 (~) 是啥意思?【英文标题】:What does the tilde (~) in macros mean?宏中的波浪号 (~) 是什么意思? 【发布时间】:2011-09-22 15:43:21 【问题描述】:在this site 上看到,代码显示使用括号中的波浪号的宏调用:
HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
// ^^^
这是什么意思/做什么?我怀疑这只是一个空洞的论点,但我不确定。它是否可能特定于 C(99),就像 __VA_ARGS__
特定于 C99 并且存在于 C++ 中?
【问题讨论】:
~ 是按位补码,您可能知道。对我来说似乎只是一个占位符。我不认为它有什么特殊含义。 【参考方案1】:在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++ 实现需要支持的基本字符集的一部分。像被忽略的标识符可能会受到宏扩展的影响,从而导致意外结果。
因此,波浪号只是一个占位符,因为需要一个参数,但没有一个参数是必需的。由于任何用户定义的标识符都可以扩展,因此您需要使用其他东西。
事实证明,与+
或-
相比,~
几乎没有被使用(二元否定并不经常被调用),因此几乎没有混淆的可能性。一旦你确定了这一点,持续使用它会给波浪号赋予新的含义;就像使用operator<<
和operator>>
处理流数据一样已经成为C++ 习惯用法。
【讨论】:
我的 +1,这是一个非常好的发现!我找不到它的任何标准参考,并且正在努力彻底理解它。您的回答很好地解决了问题。 考虑到 TINY_size 的扩展中没有出现参数(以及因此宏扩展的参数),宏扩展究竟如何导致意外结果? @Random832:宏扩展对我来说一直有点模糊,但我认为例如#define unused a, b
,现在TINY_size
将使用4 个参数而不是3 个参数调用,因此代码会被拒绝。【参考方案2】:
~
什么都不做。这些括号内的几乎所有其他内容都可以使用。
这个技巧的关键是在_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)
的扩展中测试_TRIGGER_PARENTHESIS_
是否在(~)
旁边。无论哪种方式,HAS_COMMA(...)
都将其参数扩展为 0
或 1
。
【讨论】:
我想知道这将如何与宏本身的参数一起发挥作用.._TRIGGER_PARENTHESIS_ MYMACRO (~)
.
他为什么用(~)
而不是(+)
或者别的什么?
@Johannes:Boost.Preprocessor 简介页面上提供了一个推理,我在下面引用了。目标是使用有效但稀有的预处理器令牌。【参考方案3】:
要测试的参数放在宏和它的括号之间,宏只有在参数为空时才会触发:
_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)
注意:实际上您发布的链接说明了这一点。我将在标准中检查对此的引用。
【讨论】:
请注意:是的,在发布问题后重读了几次后,它来到了我这里......这不是我第一次提出问题,几分钟后解决方案来了记住...... :(另外,你的第一句话似乎与问题没有直接关系。 @Xeo:抱歉,恐怕我对上下文的理解不够透彻,无法发布详细的答案,关于为什么只有~
存在松散的结局,我一直在破坏标准很长时间没有成功。太好了,由@Matthieu M 找到。不过,我可以安然入睡!
感谢您的努力。 :)以上是关于宏中的波浪号 (~) 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章