constexpr (C++)
Die Schlüsselwort (keyword) constexpr
wurde in C++11 eingeführt und in C++14 verbessert. Dies bedeutet constant-Ausdruck. Wie const
kann es auf Variablen angewendet werden: Ein Compilerfehler wird ausgelöst, wenn code versucht, den Wert zu modierenif. constexpr
Im Gegensatz dazu const
können auch Funktionen und Klassen-Ructors constangewendet werden. constexpr
gibt an, dass der Wert oder der Rückgabewert ant und const, sofern möglich, zur Kompilierungszeit berechnet wird.
Ein constexpr
integraler Wert kann überall verwendet werden, wo eine const ganze Zahl erforderlich ist, z. B. in Vorlagenargumenten und Arraydeklarationen. Und wenn ein Wert zur Kompilierungszeit anstelle der Laufzeit berechnet wird, hilft es Ihrem Programm, schneller zu laufen und weniger Arbeitsspeicher zu verwenden.
Um die Komplexität von Kompilierungszeit-Ant-Berechnungen und deren potenzielle Auswirkungen auf die Kompilierungszeit zu begrenzen, benötigt der C++14-Standard constdie Typen in constAnt-Ausdrücken als Literaltypen.
Syntax
constexpr
literal-type ident ier=constant-expression;if
constexpr
literal-typeidentifier{constant-expression};
constexpr
literal-typeidentifier(params);
constexpr
ctor(params);
Parameter
params
Mindestens ein Parameter, von denen jeder literaltyp sein muss und selbst ein constAnt-Ausdruck sein muss.
Rückgabewert
Eine constexpr
Variable oder Funktion muss einen Literaltyp zurückgeben.
constexpr-Variablen
Die primäreifD-Ference zwischen const
und constexpr
Variablen besteht darin, dass die Initialisierung einer const
Variablen bis zur Laufzeit zurückgestellt werden kann. Eine constexpr
Variable muss zur Kompilierungszeit initialisiert werden. Alle constexpr
Variablen sind const
.
Eine Variable kann mit
constexpr
einem Literaltyp deklariert und initialisiert werden. Wenn die Initialisierung von einem constRuctor proforMed erfolgt, muss der constRuctor alsconstexpr
deklariert werden.Ein Verweis kann so deklariert werden, als
constexpr
wenn beide Bedingungen erfüllt sind: Das referenzierte Objekt wird durch einen constAntausdruck initialisiert, und alle impliziten Konvertierungen, die während der Initialisierung aufgerufen werden, sind ebenfalls constAnt-Ausdrücke.Alle Deklarationen einer
constexpr
Variablen oder Funktion müssen dieconstexpr
Spezifikationifier aufweisen.
constexpr float x = 42.0;
constexpr float y{108};
constexpr float z = exp(5, 3);
constexpr int i; // Error! Not initialized
int j = 0;
constexpr int k = j + 1; //Error! j not a constant expression
constexpr-Funktionen
Eine constexpr
Funktion ist eine Funktion, deren Rückgabewert zur Kompilierungszeit bei Verwendung von Code erforderlich ist. Der Verbrauch von Code erfordert den Rückgabewert zur Kompilierungszeit, um eine constexpr
Variable zu initialisieren oder ein Nicht-Typ-Vorlagenargument bereitzustellen. Wenn es sich bei den Argumenten constexpr
um Werte handelt, erzeugt eine constexpr
Funktion eine Kompilierungszeit-Ant const. Wenn sie mit nicht-Argumentenconstexpr
aufgerufen wird oder der Wert zur Kompilierungszeit nicht erforderlich ist, erzeugt sie zur Laufzeit einen Wert wie eine normale Funktion. (Mit diesem dualen Verhalten können Sie keine Versionen derselben Funktion schreiben constexpr
und nichtconstexpr
verwenden.)
Eine Funktion oder constein constexpr
Ructor ist implizit inline
.
Die folgenden Regeln gelten für constexpr Funktionen:
Eine
constexpr
Funktion muss nur Literaltypen akzeptieren und zurückgeben.Eine
constexpr
Funktion kann rekursiv sein.Seifore C++20, eine
constexpr
Funktion kann nicht virtuell sein, und ein constRuctor kann nicht so definiert werden,constexpr
als wenn die eingeschlossene Klasse über virtuelle Basisklassen verfügt. In C++20 und höher kann eineconstexpr
Funktion virtuell sein. Visual Studio 2019, Version 16.10 und höher, unterstützenconstexpr
virtuelle Funktionen, wenn Sie die/std:c++20
Compileroption oder höher festlegenif.Der Text kann als
= default
oder= delete
definiert werden.Der Textkörper kann keine
goto
Anweisungen odertry
Blöcke enthalten.Eine explizite Spezialisierung einer Nicht-Vorlage
constexpr
kann wieconstexpr
folgt deklariert werden:Eine explizite Spezialisierung einer
constexpr
Vorlage muss nicht auch seinconstexpr
:
Die folgenden Regeln gelten für constexpr
Funktionen in Visual Studio 2017 und höher:
Es kann Anweisungen und
switch
Anweisungen sowie alle Schleifenanweisungen enthaltenif
, einschließlichfor
, bereichsbasiertfor
,while
und do-while.Sie kann lokale Variablendeklarationen enthalten, die Variable muss jedoch initialisiert werden. Er muss ein Literaltyp sein und darf nicht lokal sein
static
. Die lokal deklarierte Variable ist nicht erforderlich und kann mutiert werdenconst
.Eine
constexpr
Nicht-Member-Funktionstatic
ist nicht implizitconst
erforderlich.
constexpr float exp(float x, int n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp(x * x, n / 2) :
exp(x * x, (n - 1) / 2) * x;
}
Tipp
Im Visual Studio-Debugger können Sie beim Debuggen eines nicht optimierten Debugbuilds feststellen, ob eine constexpr
Funktion zur Kompilierungszeit ausgewertet wird, indem Sie einen Haltepunkt darin einfügen. Wenn der Haltepunkt erreicht wird, wurde die Funktion zur Laufzeit aufgerufen. Wenn dies nicht der Fall ist, wurde die Funktion zum Zeitpunkt der Kompilierung aufgerufen.
extern constexpr
Die Compileroption /Zc:externConstexpr bewirkt, dass der Compiler externe Verknüpfungen auf Variablen anwendet, die mithilfe von extern constexprdeklariert werden. In früheren Versionen von Visual Studio, entweder standardmäßig oder wenn /Zc:externConstexpr- angegebenifist, wendet Visual Studio interne Verknüpfungen auf constexpr
Variablen an, auch wenn die extern
Schlüsselwort (keyword) verwendet wird. Die Option "/Zc:externConstexpr " ist ab Visual Studio 2017 Update 15.6 verfügbar und ist standardmäßig deaktiviert. Die Option "/permissive" aktiviert nicht /Zc:externConstexpr.
Beispiel
Das folgende Beispiel zeigt constexpr
Variablen, Funktionen und einen benutzerdefinierten Typ. In der letzten Anweisung in main()
der constexpr
Memberfunktion GetValue()
handelt es sich um einen Laufzeitaufruf, da der Wert zur Kompilierungszeit nicht bekannt sein muss.
// constexpr.cpp
// Compile with: cl /EHsc /W4 constexpr.cpp
#include <iostream>
using namespace std;
// Pass by value
constexpr float exp(float x, int n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp(x * x, n / 2) :
exp(x * x, (n - 1) / 2) * x;
}
// Pass by reference
constexpr float exp2(const float& x, const int& n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp2(x * x, n / 2) :
exp2(x * x, (n - 1) / 2) * x;
}
// Compile-time computation of array length
template<typename T, int N>
constexpr int length(const T(&)[N])
{
return N;
}
// Recursive constexpr function
constexpr int fac(int n)
{
return n == 1 ? 1 : n * fac(n - 1);
}
// User-defined type
class Foo
{
public:
constexpr explicit Foo(int i) : _i(i) {}
constexpr int GetValue() const
{
return _i;
}
private:
int _i;
};
int main()
{
// foo is const:
constexpr Foo foo(5);
// foo = Foo(6); //Error!
// Compile time:
constexpr float x = exp(5, 3);
constexpr float y { exp(2, 5) };
constexpr int val = foo.GetValue();
constexpr int f5 = fac(5);
const int nums[] { 1, 2, 3, 4 };
const int nums2[length(nums) * 2] { 1, 2, 3, 4, 5, 6, 7, 8 };
// Run time:
cout << "The value of foo is " << foo.GetValue() << endl;
}
Anforderungen
Visual Studio 2015 oder eine höhere Version.
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Tickets als Feedbackmechanismus für Inhalte auslaufen lassen und es durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unter:Einreichen und Feedback anzeigen für