In C++ gibt es compile-time (Konstanten zur Kompilierungszeit) und link-time (zur Linkzeit) Konstanten.
const-Variable ist ein Objekt, das nach der Initialisierung nicht mehr geändert werden kann. Aber const garantiert nicht immer, dass der Wert zur Kompilierungszeit bekannt ist; er kann erst zur Laufzeit berechnet werden.constexpr garantiert, dass der Ausdruck oder die Funktion bereits zur Kompilierungszeit berechnet wird.Beispiel:
const int x = time(0); // const, aber NICHT constexpr: Wert wird zur Laufzeit berechnet constexpr int y = 2 + 2; // constexpr: zur Kompilierungszeit bekannt constexpr int square(int x) { return x * x; } int arr[square(3)]; // Arraygröße ist ein Ausdruck zur Kompilierungszeit
Verwenden Sie constexpr für konstante Ausdrücke, die dem Compiler zur Verfügung stehen müssen, z. B. für Arraygrößen oder Template-Parameter.
Kann eine als constexpr deklarierte Funktion mit nicht-konstanten Argumenten aufgerufen werden?
Antwort: Ja! Wenn die Argumente zur Kompilierungszeit bekannt sind, wird das Ergebnis zur Kompilierungszeit berechnet. Wenn die Argumente nur zur Laufzeit bekannt sind, wird die Funktion wie eine normale berechnet.
constexpr int double_val(int x) { return x * 2; } int val = std::rand(); int result = double_val(val); // Wird zur Laufzeit aufgerufen
Geschichte
Eines der Module legte die Größe des Arrays über
const intfest, in der Annahme, dass es sich um eine Konstanten zur Kompilierungszeit handelt. Bei einem anderen Compiler führte dies zu einem Fehler, da der Wert zur Laufzeit berechnet wurde und die Arraygröße nicht dem Standard entsprach.
Geschichte
Bei der Berechnung von Hashes konnte der Compiler die Berechnungen nicht optimieren, da eine
const-Variable anstelle vonconstexprverwendet wurde. Ergebnis: Reduzierung der Leistung um mehr als das 2-fache in neuen Releases.
Geschichte
Bei der Migration auf moderne Standards wurden die Schlüsselwörter verwechselt und die Funktion als
constund nicht alsconstexprdeklariert, was die Verwendung des Ergebnisses in compile-time Template-Ausdrücken verhinderte. Eine schnelle Diagnose zeigte den Fehler, aber bei der Überprüfung ging er ins Master-Branch.