質問
マクロを使用して、次のような展開されたループをコーディングします:(愚かな例)
#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 を渡すことができるため、このマクロが好きです。
質問:2番目のマクロのようなforのような構文の最初のループのようなループを定義する方法はありますか?
解決
Boost プリプロセッサライブラリを確認できます。あらゆる種類のループ処理を実行できます。構文は素晴らしいものではありませんが、うまくいくと思います。ただし、自分では使用していません。
他のヒント
イテレータオブジェクトの使用を避ける正当な理由はありますか? 最初のマクロはinstrコードの4倍のペーストを考慮する必要があります...
それ以外の場合、単純な:
#define foreach_smallprime(ii) for(int ii = 0; ii <= 7; ii = next_prime(ii) )
next_prime(ii)
をマクロと同じファイルで定義します。
質問:2番目のマクロのような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'を使用するのはおそらく適切ではありません。それを改善する他の方法があると確信していますが、これは基本的にあなたが求めているものです。