1

私はマクロを使用して、次のように展開されたループをコーディングします:(愚かな例)

#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;
}

変数名をパラメーターとして渡すことができるので、このマクロが好きです。

質問:2番目のマクロのようなfor-like構文で最初のループのようなループを定義する方法はありますか?

4

3 に答える 3

7

Boostプリプロセッサライブラリを確認できます。あらゆる種類のループ処理を実行できます。構文は良くありませんが、うまくいくと思います。ただし、私自身は使用していません。

于 2009-05-06T11:43:17.570 に答える
0

質問:2番目のマクロのようなfor-like構文で最初のループのようなループを定義する方法はありますか?

素数のワーキングセットが比較的少ないと思うので、素数のルックアップを作成するのはそれほど面倒ではありません。より多くの素数のリストを生成する必要がある場合は、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'を使用することはおそらく悪い選択です。それを改善する方法は他にもあると思いますが、これは基本的にあなたが求めているものです。

于 2009-05-06T13:13:19.507 に答える
0

イテレータ オブジェクトの使用を避ける正当な理由はありますか? 最初のマクロは、インストルメント コードの 4 倍に貼り付けられることを考慮する必要があります...

それ以外の場合は、単純な :

#define foreach_smallprime(ii) for(int ii = 0; ii <= 7; ii = next_prime(ii) )

next_prime(ii)マクロと同じファイルに定義されています。

于 2009-05-06T11:53:58.857 に答える