题
我使用宏来编码展开的循环,如下所示:(愚蠢的例子)
#define foreach_small_prime(p, instr) { \
int p; \
p = 2; instr; \
p = 3; instr; \
p = 5; instr; \
p = 7; instr; \
}
foreach_small_prime(pp, cout << pp);
int sum = 0;
foreach_small_prime(pp, {
sum += pp;
if (sum >= 10) cout << sum << endl;
});
但在某些情况下,我可能会使用构造:
#define foreach_small_even(ii) for(int ii = 0; ii < 20; ii += 2)
int sum = 0;
foreach_small_even(pp) {
sum += pp;
if (sum >= 10) cout << sum << endl;
}
我喜欢这个宏,因为我可以将变量 name 作为参数传递。
问题:有没有办法像第二个宏那样用类似for语法的第一个定义循环?
解决方案
您可以查看Boost 预处理器库。它可以做各种循环的事情。语法不是很好,但我相信它有效。但是,我自己并没有使用它。
其他提示
你有充分的理由避免使用迭代器对象吗? 你必须考虑你的第一个宏贴4x你的instr代码...
否则,简单:
#define foreach_smallprime(ii) for(int ii = 0; ii <= 7; ii = next_prime(ii) )
与 next_prime(ii)
在与宏相同的文件中定义。
问题:有没有办法像第二个宏那样用类似for语法的第一个定义循环?
我猜你有一个相对较小的素数工作集,所以创建一个素数的查找应该不会太麻烦。如果你需要生成一个更大的素数列表,我肯定在Boost库中有一些编译时模板元编程魔法。如果你有一个更复杂的数字序列,那么将查找转换为一个在生成结果时缓存结果的函数可能是明智的。
const int small_primes[MAX_SMALL_PRIMES] = {2, 3, 5, 7, 11, 13};
#define foreach_small_prime(pp) \
for (int i = 0; i < MAX_SMALL_PRIMES; pp = small_primes[++i])
用作:
void f() {
int sum = 0;
int temp = 0;
foreach_small_prime(temp) {
sum += temp;
if (sum >= 10) cout << sum << endl;
}
}
可能希望抛出查找表和MAX_SMALL_PRIMES它们的命名空间以避免混乱......并且在宏中使用常用的标识符“i”可能是一个糟糕的选择。我确信还有其他方法可以改进它,但这基本上就是你所要求的。
不隶属于 StackOverflow