Beides const
und constexpr
kann auf Variablen und Funktionen angewendet werden. Obwohl sie einander ähnlich sind, handelt es sich tatsächlich um sehr unterschiedliche Konzepte.
Beides const
und constexpr
bedeuten, dass ihre Werte nach ihrer Initialisierung nicht mehr geändert werden können. Also zum Beispiel:
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.
Der Hauptunterschied zwischen const
und constexpr
ist der Zeitpunkt, zu dem ihre Initialisierungswerte bekannt sind (ausgewertet werden). Während die Werte von const
Variablen sowohl zur Kompilierungszeit als auch zur Laufzeit constexpr
ausgewertet werden können, werden sie immer zur Kompilierungszeit ausgewertet. Zum Beispiel:
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.
Der Hauptvorteil zu wissen, ob der Wert zur Kompilierungszeit oder zur Laufzeit bekannt ist, ist die Tatsache, dass Kompilierungszeitkonstanten immer dann verwendet werden können, wenn Kompilierungszeitkonstanten benötigt werden. In C ++ können Sie beispielsweise keine C-Arrays mit variablen Längen angeben.
int temp=rand(); // temp is generated by the the random generator at runtime.
int array1[10]; // OK.
int array2[temp]; // ERROR.
Das heißt also:
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.
So const
Variablen beide definieren kann Kompilierung Konstanten wie size1
verwendet werden können , dass Feldgrößen und zu spezifizieren Laufzeitkonstanten wie size2
nur zur Laufzeit, die bekannt ist und nicht verwendet werden können , Feldgrößen zu definieren. constexpr
Definieren Sie andererseits immer Kompilierungszeitkonstanten, die Arraygrößen angeben können.
Beides const
und constexpr
kann auch auf Funktionen angewendet werden. Eine const
Funktion muss eine Elementfunktion (Methode, Operator) sein, bei der die Anwendung eines const
Schlüsselworts bedeutet, dass die Methode die Werte ihrer Elementfelder (nicht statisch) nicht ändern kann. Zum Beispiel.
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 constexpr
ist ein anderes Konzept. Es markiert eine Funktion (Mitglied oder Nichtmitglied) als die Funktion, die zur Kompilierungszeit ausgewertet werden kann, wenn Konstanten zur Kompilierungszeit als Argumente übergeben werden . Zum Beispiel können Sie dies schreiben.
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.
Übrigens sind die constexpr
Funktionen die regulären C ++ - Funktionen, die aufgerufen werden können, auch wenn nicht konstante Argumente übergeben werden. In diesem Fall erhalten Sie jedoch die Nicht-Constexpr-Werte.
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.
Das constexpr
kann auch auf die Elementfunktionen (Methoden), Operatoren und sogar Konstruktoren angewendet werden. Zum Beispiel.
class test2
{
static constexpr int function(int value)
{
return(value+1);
}
void f()
{
int x[function(10)];
}
};
Eine "verrücktere" Probe.
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.
constexpr
erstellt eine Kompilierungszeitkonstante;const
bedeutet einfach, dass der Wert nicht geändert werden kann.