Unterschied zwischen " constexpr` und `const`
Was ist der Unterschied zwischen constexpr
und const
?
- Wann kann ich die Verwendung nur einer von Ihnen?
- Wann kann ich beide verwenden und wie soll ich mich entscheiden?
constexpr
erzeugt einen compile-Zeit-Konstante; const
bedeutet einfach, dass der Wert nicht geändert werden.Teilmenge: stackoverflow.com/questions/13346879/...
Siehe auch Wenn Sie verwenden sollten constexpr-Funktion in C++11?
Kann diesem Artikel aus
boost/hana
Bibliothek kann enlight einige constexpr
Fragen, wo Sie verwenden können constexpr
und wo Sie nicht können: boost.org/doc/libs/1_69_0/libs/hana/doc/html/...InformationsquelleAutor MBZ | 2013-01-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Grundlegenden Bedeutung und der syntax
Beide keywords verwendet werden können, die in der Erklärung der Objekte als auch Funktionen. Der grundlegende Unterschied ist der, wenn angewandt, um Objekte ist diese:
const
deklariert ein Objekt als Konstante. Dies bedeutet eine Garantie, dass, sobald Sie initialisiert wurde, wird der Wert des Objekts nicht ändern, und der compiler kann nutzen diese Tatsache für Optimierungen. Es hilft auch verhindern, dass die Programmierer schreiben code, der modifiziert Objekte, die nicht dazu bestimmt sind, geändert werden nach der Initialisierung.constexpr
deklariert ein Objekt als fit für den Einsatz in dem, was der Standard fordert Konstante Ausdrücke. Aber beachten Sie, dassconstexpr
ist nicht der einzige Weg, dies zu tun.Wenn Funktionen der grundlegende Unterschied ist dieser:
const
können nur verwendet werden für nicht-statische member-Funktionen, keine Funktionen im Allgemeinen. Es gibt eine Garantie, dass die member-Funktion nicht ändern, die nicht-statischen Daten-member.constexpr
kann verwendet werden mit beiden member und nicht-member-Funktionen sowie Konstruktoren. Es erklärt die Funktion fit für den Einsatz in Konstante Ausdrücke. Der compiler wird nur akzeptieren, wenn die Funktion die bestimmte Kriterien erfüllt (7.1.5/3,4), am wichtigsten ist (†):return
- Anweisung erlaubt ist. Bei einem Konstruktor nur eine Initialisierungs-Liste, typedefs und statische geltend machen dürfen. (= default
und= delete
sind erlaubt, auch, obwohl.)asm
Erklärung, einegoto
- Anweisung wird eine Anweisung mit einem label andere alscase
unddefault
, try-block, der die definition einer Variablen von nicht-wörtliche Art, die definition einer Variablen von statischen oder thread Lagerung Dauer, die definition einer Variablen, für die keine Initialisierung durchgeführt wird.Konstante Ausdrücke
Wie gesagt,
constexpr
erklärt sowohl Objekte als auch Funktionen als fit für den Einsatz in Konstanten-Ausdrücke. Ein konstanter Ausdruck ist mehr als nur Konstante:Kann an Orten eingesetzt werden, erfordern, dass der compile-Zeit-Auswertung, zum Beispiel, template-Parameter und der array-Größe-Bezeichner:
Aber Achtung:
Deklarieren etwas als
constexpr
nicht unbedingt garantieren, dass Sie zur Kompilierzeit ausgewertet. Es verwendet werden kann für solche, aber es kann verwendet werden, in anderen Orten, die zur Laufzeit ausgewertet, wie gut.Einem Objekt kann fit sein für den Einsatz in Konstanten-Ausdrücke ohne erklärt wird
constexpr
. Beispiel:Dies ist möglich, weil
N
, Konstante und initialisiert werden bei der Deklaration mit einem literal, erfüllt die Kriterien für die ein konstanter Ausdruck sein, auch wenn es nicht deklariertconstexpr
.Also, wenn ich tatsächlich verwenden
constexpr
?Einer Objekt wie
N
oben kann verwendet werden, als Konstanten Ausdruck ohne erklärt wirdconstexpr
. Dies gilt für alle Objekte:const
[Dies ist aufgrund von §5.19/2: Eine Konstante Ausdruck muß nicht auch ein Teilausdrücke, die sich um "eine lvalue-rvalue-Modifikation, es sei denn, [ ... ] eine glvalue von integralen oder Aufzählungstyp [...]" Dank an Richard Smith für die Korrektur meiner früheren Behauptung, dass dies gilt für alle literal-Typen.]
Für eine Funktion fit zu sein für den Einsatz in Konstanten-Ausdrücke, es muss explizit deklariert werden
constexpr
; es genügt nicht, dass es nur um die Kriterien für die constant-expression-Funktionen. Beispiel:Wann kann ich /sollte ich beide verwenden,
const
undconstexpr
zusammen?A. Im Objekt-Deklarationen. Dies ist nie nötig, wenn beide Wörter beziehen sich auf das gleiche Objekt deklariert werden.
constexpr
impliziertconst
.ist das gleiche wie
Beachten Sie jedoch, dass es möglicherweise Situationen, wenn die Schlüsselwörter beziehen sich jeweils auf die verschiedenen Teile der Erklärung:
Hier
NP
ist deklariert als eine Adresse konstanter-Ausdruck, d.h. ein Zeiger ist, dass sich ein konstanter Ausdruck. (Dies ist möglich, wenn die Adresse, die erzeugt wird durch anwenden der Adress-operator auf eine statische/Globale Konstanten Ausdruck.) Hier sind sowohlconstexpr
undconst
sind erforderlich:constexpr
bezieht sich immer auf den Ausdruck erklärt wird (hierNP
), währendconst
bezieht sich aufint
(es deklariert einen Zeiger-auf-const). Entfernen derconst
machen würde der Ausdruck illegale (weil (a) ein Zeiger auf non-const-Objekt kann nicht ein konstanter Ausdruck sein, und (b)&N
ist in der Tat eine Zeiger-Konstante).B. In den Funktionsdeklarationen. In C++11,
constexpr
impliziertconst
, während in C++14 und C++17, dass ist nicht der Fall. Eine member-Funktion deklariert in C++11 alsdeklariert werden muss, wie
unter C++14, um noch nutzbar als
const
Funktion.Sicher. Mein Hauptpunkt ist, dass, wenn Sie nennen ein
constexpr
Funktion auf einem nicht-konstanter Ausdruck, wie z.B. eine gewöhnliche variable, diese ist vollkommen legal und die Funktion wird verwendet, wie jede andere Funktion. Es wird nicht zur Kompilierzeit ausgewertet (weil es nicht). Vielleicht denken Sie, dass ist offensichtlich-aber wenn ich erklärte, dass eine Funktion deklariert alsconstexpr
wird immer ausgewertet werden zur compile-Zeit, könnte es interpretiert in die falsche Richtung.Ja, ich Rede
constexpr
Objekte und nicht Funktionen. Ich denke gern anconstexpr
auf Objekte als erzwingen eines compile-Zeit-Auswertung von Werten, undconstexpr
auf Funktionen erlaubt, die die Funktion zur Kompilierzeit ausgewertet, oder zur Zeit als angemessen.Siehe 5.19/2: "eine lvalue-rvalue-Konvertierung, es sei denn, es angewendet wird [...]". Clang sollte dies durchzusetzen, korrekt; bitte Datei Fehler, wenn Sie sonst finden.
Dieser Satz: Es gibt eine Garantie, dass die member-Funktion nicht ändern, die nicht-statischen Daten-member. findet ein wichtiges detail. Mitglieder gekennzeichnet
mutable
kann auch geändert werden, indemconst
member-Funktionen.InformationsquelleAutor jogojapan
const
gilt für Variablen, und verhindert, dass Sie geändert in Ihrem code.constexpr
sagt dem compiler, dass diese Ausdruck Ergebnisse in einem compile-Zeit Konstanten Wert, so kann er an Orten eingesetzt werden, wie array-Längen, die Zuordnung zuconst
Variablen, etc. Die link gegeben durch Oli hat viele hervorragende Beispiele.Im Grunde genommen sind das 2 unterschiedliche Konzepte zusammen, und können (und sollten) verwendet werden, zusammen.
InformationsquelleAutor Karthik T
Übersicht
const
garantiert, dass ein Programm nicht ändert ein Objekt den Wert. Allerdingsconst
garantiert nicht die Art der Initialisierung des Objekts erfährt.Betrachten:
Die Funktion
max()
bloß gibt einen Literalwert. Da jedoch der Initialisierung wird eine Funktion aufgerufen, diemx
erfährt runtime-Initialisierung. Daher können Sie nicht verwenden Sie es als eine konstanter Ausdruck:constexpr
ist eine neue C++11 Schlüsselwort, das befreit Sie von der Notwendigkeit, um Makros zu erstellen und hardcoded Literale. Es garantiert auch, unter bestimmten Bedingungen, Objekte Durchlaufen statische Initialisierung. Sie kontrolliert die Bewertung der Zeit eines Ausdrucks. Mit der Durchsetzung compile-time-Auswertung der seinen Ausdruck,constexpr
können Sie definieren, true Konstante Ausdrücke , sind entscheidend für Zeitkritische Anwendungen, system-Programmierung, Vorlagen und generell in jedem code, der setzt auf die compile-Zeit-Konstanten.Constant-expression-Funktionen
Einen constant-expression-Funktion ist eine Funktion deklariert
constexpr
. Ihr Körper muss nicht virtuell und bestehen aus einer einzigen return-Anweisung nur, abgesehen von Typdefinitionen und statisch behauptet. Seine Argumente und Rückgabewert müssen literal-Typen. Es kann verwendet werden, mit nicht-Konstanten-Ausdruck-Argumente, aber wenn das geschehen ist, das Resultat ist nicht ein konstanter Ausdruck.Einem Konstanten-Ausdruck-Funktion ist dazu gedacht zu ersetzen Makros und hardcoded Literale ohne Einbußen bei Leistung oder Sicherheit geben.
Constant-expression-Objekte
Einen constant-expression-Objekt wird ein Objekt deklariert
constexpr
. Es muss initialisiert werden, mit einem Konstanten Ausdruck, oder ein rvalue konstruiert, indem ein konstanter Ausdruck Konstruktor mit constant-expression Argumente.Einen constant-expression-Objekt verhält sich so, als wenn es wurde erklärt
const
, außer dass es erfordert die Initialisierung vor der Verwendung und seine Initialisierung muss ein konstanter Ausdruck sein. Folglich ein konstanter Ausdruck ein Objekt kann immer verwendet werden, als Teil einer anderen Konstanten Ausdruck.Constant-expression Konstruktoren
Einen Konstanten-Ausdruck Konstruktor ist ein Konstruktor deklariert
constexpr
. Es kann eine member-Initialisierungs-Liste, aber seinen Körper muss leer sein, abgesehen von Typdefinitionen und statisch behauptet. Seine Argumente müssen literal-Typen.Einem Konstanten-Ausdruck Konstruktor kann der compiler initialisiert das Objekt zur compile-Zeit, vorausgesetzt, dass der Konstruktor die Argumente sind alle Konstanten-Ausdrücke.
Tipps aus dem Buch Effektives Modernes C++ von Scott Meyers über
constexpr
:constexpr
Objekte sind const und initialisiert mit Werten, die während der Kompilierung bekannt;constexpr
Funktionen erzeugen compile-Zeit ergibt beim Aufruf mit Argumenten, deren Werte bekannt sind, bei der Kompilierung;constexpr
Objekte und Funktionen verwendet werden können, in einem breiteren Spektrum von Kontexten als nicht -constexpr
- Objekte und-Funktionen;constexpr
ist Teil eines Objekts oder einer Funktion der Schnittstelle.Quelle:
Mit constexpr zur Verbesserung von Sicherheit, Leistung und Kapselung in C++.
InformationsquelleAutor zangw
Laut Buch "The C++ Programming Language, 4th Edition" von Bjarne Stroustrup
• const: Bedeutung in etwa "ich verspreche nicht, diesen Wert zu ändern" (§7.5). Dies ist in Erster Linie verwendet
spezifizieren Schnittstellen, so dass die Daten können an Funktionen übergeben werden, ohne Angst haben es geändert wird.
Der compiler erzwingt die Versprechen, const.
• constexpr: Bedeutung in etwa "werden zur Kompilierzeit ausgewertet werden" (§10.4). Dies ist in Erster Linie verwendet, um anzugeben, Konstanten, zu ermöglichen
Zum Beispiel:
Für eine Funktion nutzbar sein in einem Konstanten-Ausdruck, d.h. ein Ausdruck sein, der ausgewertet wird
durch den compiler, es muss definiert werden, constexpr.
Zum Beispiel:
Werden constexpr Funktion muss ziemlich einfach sein: nur eine return-Anweisung berechnen eines Werts. Ein
constexpr-Funktion kann verwendet werden, für die nicht-Konstanten-Argumenten, aber wenn das getan ist, ist das Ergebnis nicht ein
konstanter Ausdruck. Wir ermöglichen eine constexpr-Funktion aufgerufen werden, die mit nicht-Konstanten-Ausdruck-Argumente
in Kontexten, die nicht erfordern Konstante Ausdrücke, so dass wir nicht hav e zu definieren, die im wesentlichen
die gleiche Funktion zweimal: einmal für Konstante Ausdrücke und einmal für Variablen.
In ein paar Orte, Konstante Ausdrücke erforderlich sind, die durch Sprache Regeln (z.B. array-Grenzen (§2.2.5,
§7.3), case-Bezeichnungen (§2.2.4, §9.4.2), template-Argumente (§25.2), und Konstanten deklariert, mit
constexpr). In anderen Fällen, compile-Zeit-Auswertung ist wichtig für die Leistung. Unabhängig von
performance-Probleme, die Vorstellung von der Unveränderlichkeit (von einem Objekt mit einem unveränderbaren Zustand) ist ein
wichtige design-Sorge (§10.4).
InformationsquelleAutor Mustafa Ekici
Beide
const
undconstexpr
angewendet werden können, um Variablen und Funktionen. Obwohl Sie einander ähnlich, in der Tat, Sie sind sehr unterschiedliche Konzepte.Beide
const
undconstexpr
bedeuten, dass Ihre Werte können nicht geändert werden, nach Ihrer Initialisierung. So zum Beispiel:Den prinzipiellen Unterschied zwischen
const
undconstexpr
ist die Zeit, wenn Ihre Initialisierung Werte bekannt sind (ausgewertet). Während die Werte derconst
Variablen ausgewertet werden können, sowohl auf compile-Zeit und Laufzeitconstexpr
sind immer zur Kompilierzeit ausgewertet. Zum Beispiel:Den entscheidenden Vorteil zu wissen, ob der Wert bekannt ist, zur Kompilierungszeit oder Laufzeit, ist die Tatsache, dass die compile-Zeit-Konstanten können verwendet werden, wenn eine compile-Zeit-Konstanten erforderlich sind. Zum Beispiel, C++ kann man nicht mit angeben C-arrays mit der Länge variabel.
So bedeutet es, dass:
So
const
Variablen definieren können sowohl compile-Zeit-Konstanten wiesize1
können verwendet werden, um anzugeben, array-Größen und Laufzeit-Konstanten wiesize2
bekannt sind nur zur Laufzeit und kann nicht verwendet werden, um zu definieren, array-Größen. Auf der anderen Seiteconstexpr
immer definieren compile-Zeit-Konstanten, die angeben können, die array-Größen.Beide
const
undconstexpr
angewendet werden können, um Funktionen zu. Einconst
Funktion muss eine member-Funktion (Methode, operator) wenn der Antrag vonconst
keyword bedeutet, dass die Methode nicht ändern können Sie die Werte von Ihrem Mitglied (nicht-statischen) Felder. Zum Beispiel.Einen
constexpr
ist ein anderes Konzept. Es markiert eine Funktion (Mitglied oder nicht-Mitglied) als die Funktion, die ausgewertet werden können zur compile-Zeit wenn compile-Zeit-Konstanten übergeben werden, die als Ihre Argumente. Zum Beispiel können Sie schreiben diese.Durch die Art und Weise der
constexpr
Funktionen sind das normale C++ - Funktionen, die aufgerufen werden können, auch wenn nicht-Konstante Argumente übergeben werden. Aber in diesem Fall, Sie werden immer das non-constexpr-Werte.Den
constexpr
kann auch angewendet werden, um die member-Funktionen (Methoden), die Betreiber und auch Konstruktoren. Zum Beispiel.Mehr 'verrückt' sample.
constexpr int
existiert, aber es buchstabiertconst int
InformationsquelleAutor Timmy_A
Als @0x499602d2 bereits darauf hingewiesen,
const
nur sichergestellt, dass ein Wert nicht geändert werden, nachdem die Initialisierung, wo, wieconstexpr
(Einführung in C++11) gewährleistet die variable ist eine compile-Zeit-Konstante.Betrachten Sie das folgende Beispiel(aus LearnCpp.com):
InformationsquelleAutor Lokesh Meher
Einen
const int var
kann dynamisch eingestellt auf einen Wert, der Laufzeit und einmal ist es auf den Wert gesetzt, kann es nicht mehr geändert werden.Einen
constexpr int var
nicht dynamisch zur Laufzeit, sondern zur compile-Zeit. Und einmal ist es auf den Wert gesetzt, kann es nicht mehr geändert werden.Hier ist ein solides Beispiel:
Dem snippet oben kompiliert in Ordnung und ich kommentiert haben, diejenigen, die ihn verursachen Fehler.
InformationsquelleAutor typelogic