Les deux constet constexprpeuvent être appliqués aux variables et aux fonctions. Même s'ils se ressemblent, ce sont en fait des concepts très différents.
Les deux constet constexprsignifient que leurs valeurs ne peuvent pas être modifiées après leur initialisation. Ainsi, par exemple:
const int x1=10;
constexpr int x2=10;
x1=20; // ERROR. Variable 'x1' can't be changed.
x2=20; // ERROR. Variable 'x2' can't be changed.
La principale différence entre constet constexprest le moment où leurs valeurs d'initialisation sont connues (évaluées). Bien que les valeurs des constvariables puissent être évaluées au moment de la compilation et à l'exécution, elles constexprsont toujours évaluées au moment de la compilation. Par exemple:
int temp=rand(); // temp is generated by the the random generator at runtime.
const int x1=10; // OK - known at compile time.
const int x2=temp; // OK - known only at runtime.
constexpr int x3=10; // OK - known at compile time.
constexpr int x4=temp; // ERROR. Compiler can't figure out the value of 'temp' variable at compile time so `constexpr` can't be applied here.
Le principal avantage de savoir si la valeur est connue au moment de la compilation ou à l'exécution est le fait que les constantes de temps de compilation peuvent être utilisées chaque fois que des constantes de temps de compilation sont nécessaires. Par exemple, C ++ ne vous permet pas de spécifier des tableaux C avec des longueurs variables.
int temp=rand(); // temp is generated by the the random generator at runtime.
int array1[10]; // OK.
int array2[temp]; // ERROR.
Cela signifie donc que:
const int size1=10; // OK - value known at compile time.
const int size2=temp; // OK - value known only at runtime.
constexpr int size3=10; // OK - value known at compile time.
int array3[size1]; // OK - size is known at compile time.
int array4[size2]; // ERROR - size is known only at runtime time.
int array5[size3]; // OK - size is known at compile time.
Ainsi, les constvariables peuvent définir à la fois des constantes de temps de compilation comme size1celle-ci peuvent être utilisées pour spécifier des tailles de tableau et des constantes d'exécution comme size2celles-ci ne sont connues qu'au moment de l'exécution et ne peuvent pas être utilisées pour définir des tailles de tableau. D'un autre côté, constexprdéfinissez toujours des constantes de temps de compilation qui peuvent spécifier des tailles de tableau.
Les deux constet constexprpeuvent également être appliqués aux fonctions. Une constfonction doit être une fonction membre (méthode, opérateur) où l'application du constmot clé signifie que la méthode ne peut pas modifier les valeurs de leurs champs membres (non statiques). Par exemple.
class test
{
   int x;
   void function1()
   {
      x=100; // OK.
   }
   void function2() const
   {
      x=100; // ERROR. The const methods can't change the values of object fields.
   }
};
A constexprest un concept différent. Il marque une fonction (membre ou non-membre) comme la fonction qui peut être évaluée au moment de la compilation si des constantes de temps de compilation sont passées comme arguments . Par exemple, vous pouvez écrire ceci.
constexpr int func_constexpr(int X, int Y)
{
    return(X*Y);
}
int func(int X, int Y)
{
    return(X*Y);
}
int array1[func_constexpr(10,20)]; // OK - func_constexpr() can be evaluated at compile time.
int array2[func(10,20)]; // ERROR - func() is not a constexpr function.
int array3[func_constexpr(10,rand())]; // ERROR - even though func_constexpr() is the 'constexpr' function, the expression 'constexpr(10,rand())' can't be evaluated at compile time.
Par ailleurs, les constexprfonctions sont les fonctions C ++ normales qui peuvent être appelées même si des arguments non constants sont passés. Mais dans ce cas, vous obtenez les valeurs non constexpr.
int value1=func_constexpr(10,rand()); // OK. value1 is non-constexpr value that is evaluated in runtime.
constexpr int value2=func_constexpr(10,rand()); // ERROR. value2 is constexpr and the expression func_constexpr(10,rand()) can't be evaluated at compile time.
Le constexprpeut également être appliqué aux fonctions membres (méthodes), aux opérateurs et même aux constructeurs. Par exemple.
class test2
{
    static constexpr int function(int value)
    {
        return(value+1);
    }
    void f()
    {
        int x[function(10)];
    }
};
Un échantillon plus «fou».
class test3
{
    public:
    int value;
    // constexpr const method - can't chanage the values of object fields and can be evaluated at compile time.
    constexpr int getvalue() const
    {
        return(value);
    }
    constexpr test3(int Value)
        : value(Value)
    {
    }
};
constexpr test3 x(100); // OK. Constructor is constexpr.
int array[x.getvalue()]; // OK. x.getvalue() is constexpr and can be evaluated at compile time.
               
              
constexprcrée une constante de compilation;constsignifie simplement que la valeur ne peut pas être modifiée.