我使用宏来编码展开的循环,如下所示:(愚蠢的例子)

#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”可能是一个糟糕的选择。我确信还有其他方法可以改进它,但这基本上就是你所要求的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top