const vs constexpr sur les variables
Est-il une différence entre les définitions suivantes?
const double PI = 3.141592653589793;
constexpr double PI = 3.141592653589793;
Si non, le style est préféré à C++11?
- Superset: stackoverflow.com/questions/14116003/...
Vous devez vous connecter pour publier un commentaire.
Je crois qu'il existe une différence. Nous allons renommer pour que nous puissions en parler plus facilement:
Les deux
PI1
etPI2
sont constants, ce qui signifie que vous ne pouvez pas les modifier. Cependant seulementPI2
est une constante de compilation. Il est être initialisé au moment de la compilation.PI1
peut être initialisé au moment de la compilation ou de l'exécution. En outre, seulementPI2
peut être utilisé dans un contexte qui nécessite une constante de compilation. Par exemple:mais:
et:
mais:
Que vous devez utiliser? Utilisez celui qui répond à vos besoins. Ne vous voulez vous assurer que vous avez un moment de la compilation constante qui peut être utilisé dans des contextes où une constante de compilation est nécessaire? Voulez-vous être en mesure de les initialiser avec un calcul fait au moment de l'exécution? Etc.
const int N = 10; char a[N];
œuvres, et les limites du tableau doivent être des constantes de compilation.PI1
à un moment de la compilation intégrale constante pour une utilisation dans un tableau, mais pas pour une utilisation en tant que non-type intégral paramètre du modèle. De sorte que le moment de la compilation de la convertibilité dePI1
à un type intégral semble un peu hit & miss pour moi.a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression
vsa glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refers to a sub-object of such an object
. Ce n'est pas la même que la conversion implicite deint
, qui a des règles différentes.enum
initialiseur sont les deux seules différences notables entreconst
etconstexpr
(et aucun ne fonctionne pourdouble
de toute façon).size_t const int N = 10; char a[N];
fonctionne en C++, mais pas dans C (où vous avez besoin de#define N 10
).1 / PI1
et1 / PI2
peut donner des résultats différents. Je ne pense pas que cette technicité est tout aussi important que les conseils dans cette réponse, cependant.constexpr double PI3 = PI1;
fonctionne correctement pour moi. (MSVS2013 CTP). Ce que je fais mal?PI2
ont une mémoire d'exécution de l'adresse? Si oui, je me demande pourquoi, puisqu'en théorie, toutes les expressions constantes doivent être incorporé (pas besoin de garder une variable autour); surtout si cela est fait par le compilateur. L'objet final code ne devrait avoir aucune connaissance de cette variable.PI2
va avoir une liaison interne, signifie qu'elle va être locale à une unité de traduction. Il sera théoriquement disposer d'une adresse. Toutefois, si cette adresse n'est jamais utilisé, il ne doit pas exister. SiPI2
est jamais passé par référence, le compilateur besoin de le stocker quelque part pour la référence à consulter (à moins que cette fonction est incorporé et que le compilateur est capable d'optimiser loin de référence).constexpr double PI3 = PI1; // error
- L'erreur du compilateur est spécifique. Par exemple, certains compilateurs allez voir quePI1
lui-même est un littéral, et donc de résoudre ce qui est légal. D'autres, en raison de la nature deconst
, de ne pas effectuer cette vérification, car il peut ou peut ne pas être un littéral.constexpr PI3 = PI1;
, les paramètres de modèle, etc...PI1
impossible dePI2
Pas de différence ici, mais il est important quand vous avez un type qui a un constructeur.
s0
est une constante, mais il ne promet pas d'être initialisé au moment de la compilation.s1
est marquéconstexpr
, donc c'est une constante, et, parce queS
s'constructeur est également marquéeconstexpr
, il sera initialisé au moment de la compilation.Surtout, ce qui importe lors de l'initialisation au moment de l'exécution prendrait du temps et que vous voulez pousser ce travail sur le compilateur, où il est aussi beaucoup de temps, mais ne ralentit pas le temps d'exécution du programme compilé
constexpr
conduirait à un diagnostic doit le compiler en temps de calcul de l'objet est impossible. Ce qui est moins clair, c'est de savoir si une fonction attendre un paramètre constant pourrait être exécuté au moment de la compilation si le paramètre être déclaré commeconst
et non pas commeconstexpr
: c'est à dire, seraitconstexpr int foo(S)
être exécuté au moment de la compilation si je l'appellefoo(s0)
?foo(s0)
sera exécuté au moment de la compilation, mais on ne sait jamais: un compilateur est autorisé à faire de telles optimisations. Certes, ni la gcc 4.7.2 ni clang 3.2 permettez-moi de compilerconstexpr a = foo(s0);
constexpr indique une valeur constante et connue lors de la compilation.
const indique une valeur qui n'est constant; il n'est pas obligatoire de savoir lors de la compilation.
Noter que const n'offre pas les mêmes garanties que constexpr, car const
les objets n'ont pas besoin d'être initialisé avec les valeurs connues lors de la compilation.
Tous constexpr objets sont const, mais pas tous les objets const sont constexpr.
Si vous voulez compilateurs pour garantir qu'une variable a une valeur qui peut être
utilisé dans des contextes nécessitant des constantes de compilation, l'outil pour constexpr, non const.
Un constexpr constante symbolique doit être donné une valeur qui est connu au moment de la compilation.
Par exemple:
Pour gérer les cas où la valeur d'une “variable” qui est initialisé avec une valeur qui n'est pas connu au moment de la compilation, mais ne change pas après l'initialisation,
C++ offre une seconde forme de constante (une const).
Par Exemple:
Ces “const variables” sont très courantes pour deux raisons:
l'initialisation sont en eux-mêmes largement utile.
La référence : "de la Programmation: Principes et Pratique avec C++" par Stroustrup