Wenn ein Objekt als const
deklariert wird, ist dessen Wert garantiert nur zur Laufzeit verfügbar, aber wenn es als constexpr
deklariert wird, ist der Wert garantiert sowohl während der Kompilierung als auch zur Laufzeit verfügbar. Wenn ich also ein Objekt habe, dessen Wert während der Kompilierung verfügbar ist, gibt es Situationen, in denen ich es nicht als constexpr
deklarieren sollte?
Wenn bei Funktionen eine Funktion einen Wert zurückgeben kann, der während der Kompilierung berechnet wurde, wenn Argumente mit Werten übergeben wurden, die während der Kompilierung verfügbar waren, würde es Sinn machen, die Funktion constexpr
nicht zu deklarieren?
Der einzige Fall, den ich mir vorstellen kann, ist, wenn Sie nicht wollen, dass die Funktion in der Lage ist, eine Kompilierzeitkonstante zu berechnen, wenn sie mit bekannten Kompilierzeitargumenten aufgerufen wird, zB wenn Sie sie beibehalten wollen die Flexibilität, die Implementierung von midPoint
zu ändern, ohne die Schnittstelle zu ändern (wodurch Anrufer möglicherweise unterbrochen werden). Beispielsweise möchten Sie möglicherweise die Flexibilität beibehalten, um constexpr
Nebenwirkungen zu midPoint
hinzuzufügen, z. B. IO.
Für Variablen sehe ich keinen Grund, constexpr
nicht zu verwenden, wenn du kannst. Aber es ist nicht immer möglich, z.B. wenn der Initialisierer einer Variablen durch eine virtuelle Funktion, z. B.
Das Hinzufügen von constexpr
zu einer Funktion ist eine Schnittstellenänderung : Sie drücken die Tatsache aus, dass Sie damit constexpr
Variablen initialisieren können. Dies bedingt Einschränkungen bei der Implementierung Ihrer Funktion, z. B. kein Aufruf virtueller Funktionen, keine dynamische Speicherzuordnung und keine Lambda-Funktionen als Funktionsobjekte.
Beachten Sie, dass die Auflösung LWG-Ausgabe 2013 ermöglicht es den Implementierern der Standardbibliothek nicht, constexpr
zu Bibliotheksfunktionen hinzuzufügen. Einer der Gründe ist, dass das Deklarieren einer Funktion constexpr
bestimmte Debugging-Implementierungen, die dynamische Zuweisungen durchführen (insbesondere Iterator-Überprüfung), verhindern kann. Dies bedeutet, dass zukünftige Erweiterungen von constexpr
für die Standardbibliothek separate Vorschläge sein müssen. Dies steht im Gegensatz zu noexcept
, wo Bibliotheksschreiber mehr Freiheit haben.
Sie können ein const ändern:
%Vor%Dasselbe gilt für constexpr, was es dem Compiler ermöglicht, ohne Zweifel zu wissen, dass der Ausdruck zur Kompilierungszeit verfügbar ist und somit Optimierungen möglich sind.