【发布时间】:2013-12-29 07:55:14
【问题描述】:
考虑以下示例代码(我实际上使用更长的二进制字符串,但这足以解释问题):
void enumerateAllSubsets(unsigned char d) {
unsigned char n = 0;
do {
cout<<binaryPrint(n)<<",";
} while ( n = (n - d) & d );
}
函数(由于 Knuth)有效地循环遍历二进制字符串的所有子集;
例如:
33 = '00100001' in binary and enumerateAllSubsets(33) would produce:
00000000, 00100000, 00000001, 00100001.
我需要编写一个#define 来实现
macroEnumerate(n,33)
cout<<binaryPrint(n)<<",";
行为方式等同于 enumerateAllSubsets(33)。 (好吧,顺序可能会重新排列)
基本上我需要能够对集合的子集执行各种操作。
用 for 循环做类似的事情是微不足道的:
for(int i=0;i < a.size();i++)
foo(a[i]);
可以替换为:
#define foreach(index,container) for(int index=0;index < container.size();index++)
...
foreach(i,a)
foo(a[i]);
enumerateAllSubsets() 的问题是循环体需要无条件执行一次,因此 do-while 不能被重写为 for。
我知道这个问题可以通过 STL 风格的模板函数和传递给它的 lambda(类似于 STL for_each 函数)来解决,但是一些糟糕的 #define 宏似乎是一个更干净的解决方案。
【问题讨论】:
-
我很少会认为宏比函数更干净。
-
“我需要写一个#define ...”——不,你真的不需要(或想要)那个。这是一个可怕的想法。
标签: c++ c macros metaprogramming c-preprocessor