Question

J'utilise des macros pour coder des boucles déroulées comme ceci: (exemple idiot)

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

Mais dans certains cas, je pourrais utiliser pour la construction:

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

J'aime cette macro parce que je peux passer en paramètre une variable nom .

Question: Y a-t-il un moyen de définir une boucle comme la première dans une syntaxe similaire à celle de la deuxième macro?

Était-ce utile?

La solution

Vous pouvez consulter la bibliothèque du préprocesseur Boost. Il peut faire toutes sortes de choses en boucle. La syntaxe n'est pas géniale, mais je crois que cela fonctionne. Cependant, je ne l'ai pas utilisé moi-même.

Autres conseils

Avez-vous une bonne raison d'éviter d'utiliser un objet itérateur? Vous devez considérer vos premières pâtes macro 4x votre code d'instruction ...

Sinon, un simple:

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

avec next_prime (ii) défini dans le même fichier que la macro.

  

Question: Y a-t-il un moyen de définir une boucle comme la première dans une syntaxe similaire à celle de la deuxième macro?

Je suppose que vous avez un ensemble de nombres premiers relativement petit, alors créer une consultation de vos nombres premiers ne devrait pas poser trop de problèmes. Si vous devez générer une liste plus longue de nombres premiers, je suis sûr que la magie de la méta-programmation des modèles de compilation est disponible dans la bibliothèque Boost. Si vous générez une série de nombres plus complexe, il peut être judicieux de transformer la recherche en une fonction qui met en cache les résultats au fur et à mesure qu'ils sont générés.

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])

Utilisé comme:

void f() {
  int sum = 0;
  int temp = 0;
  foreach_small_prime(temp) {
    sum += temp;
    if (sum >= 10) cout << sum << endl;
  }
}

Vous voulez probablement jeter la table de recherche et MAX_SMALL_PRIMES leur propre espace de noms pour éviter tout encombrement ... et utiliser un identifiant communément utilisé 'i' dans la macro est probablement un mauvais choix. Je suis sûr qu'il existe d'autres moyens de l'améliorer, mais c'est fondamentalement ce que vous demandez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top