Permettez-moi de commencer en disant à mon intention. Autrefois (C++) jours, nous avons un code comme:
class C
{
public:
enum {SOME_VALUE=27};
};
Puis nous avons pu utiliser SOME_VALUE
tout au long de notre code de la compilation constant et où le compilateur verrait C::SOME_VALUE
, il suffit d'insérer le littéral 27.
De nos jours, il semble plus acceptable pour modifier ce code pour quelque chose comme:
class C
{
public:
static constexpr int SOME_VALUE=27;
};
Cela ressemble beaucoup plus propre, donne SOME_VALUE
un bien de type défini et semble être l'approche privilégiée comme du C++11. L' (imprévues au moins pour moi) le problème est que cela provoque également des scénarios où SOME_VALUE
doit être externe. C'est, dans certains rpc fichier quelque part, nous devons ajouter:
constexpr int C::SOME_VALUE; // Now C::SOME_VALUE has external linkage
Le cas à l'origine de cette semblent être quand const références à SOME_VALUE
sont utilisés, ce qui arrive assez souvent en C++ de la Bibliothèque Standard de code (Voir l'exemple au bas de cette question). Je suis en utilisant gcc 4.7.2 que mon compilateur par la voie.
En raison de ce dilemme, je suis obligé de revenir à la définition d' SOME_VALUE
comme un enum (c'est à dire, de la vieille école) afin d'éviter d'avoir à ajouter une définition pour un fichier cpp pour certains, mais pas tous mes statique constexpr variables membres. N'est-il pas d'une certaine façon à indiquer au compilateur qu' constexpr int SOME_VALUE=27
signifie qu' SOME_VALUE
doit être traitée seulement comme un moment de la compilation constante et jamais un objet avec une liaison externe? Si vous voyez un const référence utilisé avec elle, de créer un temporaire. Si vous voyez son adresse, de générer une erreur de compilation si il le faut, parce que c'est une compilation constante de temps et rien de plus.
Voici quelques apparence bénigne exemple de code qui fait que nous nous besoin d'ajouter la définition de l' SOME_VALUE
dans un fichier cpp (encore une fois, testé avec gcc 4.7.2):
#include <vector>
class C
{
public:
static constexpr int SOME_VALUE=5;
};
int main()
{
std::vector<int> iv;
iv.push_back(C::SOME_VALUE); // Will cause an undefined reference error
// at link time, because the compiler isn't smart
// enough to treat C::SOME_VALUE as the literal 5
// even though it's obvious at compile time
}
En ajoutant la ligne suivante dans le code à la portée de fichier peut résoudre l'erreur:
constexpr int C::SOME_VALUE;