Question

Dites que j'ai un tableau stockant les 10 premiers nombres premiers, comme ceci:

const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

Tout cela est très fin et simple tant que j'ai 1 fichier .cpp. Cependant, si j'ai plusieurs fichiers .cpp, je ne sais pas vraiment où mettre ce tableau.

Une solution évidente serait la suivante:

// primes.h:
extern const int primes[10];

// primes.cpp:
extern const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

Cependant, le problème avec cela est que le tableau des nombres premiers n'est plus une constante de temps de compilation. Disons que X.CPP veut faire des calculs lourds impliquant des nombres premiers [K], avec une constante de temps de compilation KA, il faudrait faire une recherche de mémoire réelle. Je n'aime pas ça.

Alors, où puis-je mettre ce tableau pour que:

  1. Ce n'est qu'une seule fois dans le binaire (pas une fois par fichier .cpp)
  2. Array [Some_Constant] est également une constante de temps de compilation

Éditer

que dis-tu de ça?

inline int prime(int i) {
    static const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
    return primes[i];
}

PS: Même la "solution évidente" ci-dessus m'a pris un certain temps pour écrire. Apparemment, les variables constant ont une liaison interne par défaut, j'ai donc dû ajouter "externe" au fichier pmimes.cpp pour le faire fonctionner.

Était-ce utile?

La solution

Je pense que cela devrait fonctionner (maintenant mis à jour après que les tests de Migi ont révélé un défaut):

template <bool dummy>
struct primes_lut
{
    static const int values[];
};

template<bool dummy>
const int primes_lut<dummy>::values[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

static auto& primes = primes_lut<true>::values;

(Il n'y a aucun problème en C ++ qui ne peut pas être résolu par l'utilisation de plus de modèles.)

Une autre approche:

struct primes_lut { int values[10]; };
inline const primes_lut& primes_lut_provider(void)
{
    static const primes_lut values = { {2, 3, 5, 7, 11, 13, 17, 19, 23, 29} };
    return values;
}
static const int (&primes)[10] = primes_lut_provider().values;

Enfin, aucune de ces astuces n'est nécessaire avec un linker moderne que d'implémenter le pliage constant.

Autres conseils

Vous pouvez utiliser Enum à l'intérieur d'un en-tête. Les énumérations sont garanties pour compiler des constantes de temps et (sauf si vous utilisez la classe Enum C ++ 0x) converti implicitement en entiers.

static const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

dans un fichier d'en-tête. Cela peut conduire à un exécutable plus grand (chaque fichier source aura sa propre copie du tableau) mais je pense que le même problème s'applique à la réponse actuellement acceptée.

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