宏 __COUNTER__
使用 我曾经写过如下的代码,在此记录下对于宏 __COUNTER__
的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #define RESMON_V2_REGISTER_CLASS_PLUGIN(Derived, Base, UniqueID) \ namespace { \ struct ProxyExec##UniqueID { \ typedef Derived _Derived; \ typedef Base _Base; \ ProxyExec##UniqueID() { \ register_plugin<_Derived, _Base> (#Derived, #Base); \ } \ }; \ static ProxyExec##UniqueID g_register_plugin_##UniqueID; \ } #define RESMON_V2_REGISTER_CLASS(Derived, Base, UniqueID) \ RESMON_V2_REGISTER_CLASS_PLUGIN(Derived, Base, UniqueID) #define RESMON_V2_REGISTER_MONITOR_ITEM(Derived) \ RESMON_V2_REGISTER_CLASS(Derived, baidu::pavaro::resmon_v2::MonitorItemBase, __COUNTER__)
这段代码的作用就是借助静态的全局变量会自动初始化的特点,自动调用构造函数,而在构造函数中实现一些业务逻辑,以达到程序员的目的。使用宏定义在编译时就生成这些代码,需要生成不同的全局变量。因此我们借助宏 __COUNTER__
1 2 3 4 This macro expands to sequential integral values starting from 0\. In conjunction with the ## operator, this provides a convenient means to generate unique identifiers. Care must be taken to ensure that __COUNTER__ is not expanded prior to inclusion of precompiled headers which use it. Otherwise, the precompiled headers will not be used.
__COUNTER__
是一个计数器,他会从 0 开始,然后每次都加1。而且是在编译期间进行,不用出现竞争。
如何使用 通常和 ##
一起使用,用于构建唯一的标识符。
1 2 3 #define MERGE_BODY(a, b) a##b #define MERGE(a, b) MERGE_BODY(a, b) // 因为 ‘##’ 会阻止另一个宏展开,所以需要这个中间层 #define uniqueVarName(name) MERGE(name, __COUNTER__) // 把标识符与 __COUNTER__ 合并