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, quel style est préféré en C++11?

204
demandé sur fredoverflow 2012-11-12 19:50:13

4 réponses

je crois qu'il y a une différence. Renommons - les pour qu'on puisse en parler plus facilement:

const     double PI1 = 3.141592653589793;
constexpr double PI2 = 3.141592653589793;

les deux PI1 et PI2 sont constants, ce qui signifie que vous ne pouvez pas les modifier. Cependant seulement PI2 est une constante de temps de compilation. être initialisé au moment de la compilation. PI1 peut être initialisé au moment de la compilation ou de l'exécution. En outre, seulement PI2 peut être utilisé dans un contexte qui nécessite une constante de compilation. Par exemple:

constexpr double PI3 = PI1;  // error

, mais:

constexpr double PI3 = PI2;  // ok

et:

static_assert(PI1 == 3.141592653589793, "");  // error

, mais:

static_assert(PI2 == 3.141592653589793, "");  // ok

Que devez-vous utiliser? Utilisez celui qui répond à vos besoins. Voulez-vous vous assurer que vous avez une constante de temps de compilation qui peut être utilisée dans les contextes où une constante de temps de compilation est requise? Pensez-vous voulez être en mesure de les initialiser avec un calcul fait au moment de l'exécution? Etc.

237
répondu Howard Hinnant 2018-04-05 00:32:05

aucune différence ici, mais cela importe quand vous avez un type qui a un constructeur.

struct S {
    constexpr S(int);
};

const S s0(0);
constexpr S s1(1);

s0 est une constante, mais elle ne promet pas d'être initialisée au moment de la compilation. s1 est marqué constexpr , il est donc une constante et, parce que S 's constructeur est également marqué constexpr , il sera initialisé à la compilation.

la plupart du temps cette question quand l'initialisation à l'exécution serait fastidieuse et vous voulez pousser ce travail sur le compilateur, où il prend aussi du temps, mais ne ralentit pas le temps d'exécution du programme compilé

64
répondu Pete Becker 2012-11-12 16:04:41

constexpr indique une valeur constante et connue lors de la compilation.

const indique une valeur qui est constante; il n'est pas obligatoire de savoir pendant la compilation.

int sz;
constexpr auto arraySize1 = sz;    // error! sz's value unknown at compilation
std::array<int, sz> data1;         // error! same problem

constexpr auto arraySize2 = 10;    // fine, 10 is a compile-time constant
std::array<int, arraySize2> data2; // fine, arraySize2 is constexpr

notez que const n'offre pas la même garantie que constexpr, parce que const les objets n'ont pas besoin d'être initialisés avec des valeurs connues lors de la compilation.

int sz;
const auto arraySize = sz;       // fine, arraySize is const copy of sz
std::array<int, arraySize> data; // error! arraySize's value unknown at compilation

tous les objets constexpr sont const, mais tous les objets const ne sont pas 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, pas const.

28
répondu Ajay yadav 2017-06-17 10:36:41

a constexpr la constante symbolique doit recevoir une valeur connue au moment de la compilation. Par exemple:

constexpr int max = 100; 
void use(int n)
{
    constexpr int c1 = max+7; // OK: c1 is 107
    constexpr int c2 = n+7;   // Error: we don’t know the value of c2
    // ...
}

pour gérer les cas où la valeur d'une" variable " initialisée avec une valeur qui n'est pas connue au moment de la compilation mais ne change jamais après l'initialisation, C++ offre une seconde forme de constante (une const ). Par Exemple:

constexpr int max = 100; 
void use(int n)
{
    constexpr int c1 = max+7; // OK: c1 is 107
    const int c2 = n+7; // OK, but don’t try to change the value of c2
    // ...
    c2 = 7; // error: c2 is a const
}

Ces " const variables" sont très fréquentes pour deux raisons:

  1. C++98 n'avait pas de constexpr, donc les gens ont utilisé const .
  2. élément de la liste" Variables " qui ne sont pas des expressions constantes (leur valeur n'est pas connue au moment de la compilation) mais qui ne changent pas de valeurs après l'initialisation est en soi très utile.

référence:" programmation: principes et pratique utilisant C++" par Stroustrup

10
répondu Jnana 2018-03-28 01:09:53