Bedeutet die Angabe constexpr Konstruktor auf automatisch alle Objekte daraus erstellt werden constexpr?
Hier ist mein code:
class test{
public:
constexpr test(){
}
constexpr int operator+(const test& rhs){
return 1;
}
};
int main(){
test t; //constexpr word isn't necessary
constexpr int b = t+test(); //works at compile time!
int w = 10; //ERROR constexpr required
constexpr int c = w + 2; //Requires w to be constexpr
return 0;
}
Merke ich, dass es geklappt hat, obwohl ich mich gar nicht festlegen, test constexpr
. Ich habe versucht, replizieren Sie das Ergebnis, indem Sie das gleiche machen int
aber ich bekomme Fehler. Konkret will mein int w
innerhalb der constexpr int c = w + 2;
zu constexpr
. Von meinem ersten Versuch, das mit test
, Hat es funktioniert, weil der Grund, dass ich constexpr
auf der Konstruktor bereits? Wenn das der Fall ist, dann wäre es gut davon ausgehen, dass alle Klassen, die constexpr
auf Ihre Konstruktoren werden alle instanziierten Objekte erstellt oder mit ihm zu constexpr
?
Bonus-Frage:
Wenn ich eine constexpr
Konstruktor, ist es schlecht etwas zu machen ? test * t = new test();
?
- Wenn Sie schreiben, ein Kontext, in dem die Instanz nicht constexpr, Ihre Klasse einfach nicht verwendet werden, die als literal-Klasse. Siehe meine Antwort unten für details
- Ihre
operator+
nicht auf den Wert seiner Operanden (oder, in einer Sprache, die Anwalt ist der Ansicht, dass Sie nicht durchführen "lvalue-zu-rvalue-Konvertierung" auf seiner Parameter), aberint
's Additions-operator tut.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dass ein constexpr Konstruktor nicht machen Erklärungen, die variable automatisch constexpr, so
t
ist kein constexpr. Was ist Los in diesem Fall ist, dass Sie anrufen, eine constexpr-Funktion, ist diese Zeile:angesehen werden können, wie folgt:
Also dann die Frage ist, ob
test()
ist ein konstanter Ausdruck sein, was es ist, da der Konstruktor ist constexpr und fallen nicht unter eine der Ausnahmen unter den Entwurf der C++11 standard Abschnitt5.19
[expr.const] Absatz2
sagt:und umfasst die folgenden Kugel:
Sehen wir dies leichter, indem Sie einige kleine änderungen an
test
durch die Einführung einer member-variablex
:Zugriffsversuche in
operator +
und wir können sehen, dass die folgende Zeile nicht:mit den folgenden Fehler aus clang (sehen Sie es live):
Es schlägt fehl, da
t
ist kein constexpr variable und daher Ihre Unterobjekte sind auch nicht constexpr Variablen.Ihrem zweiten Beispiel:
funktioniert nicht, denn es fällt unter eine der Ausnahmen in den Entwurf der C++11 standard Abschnitt
5.19
[expr.const] :Dem Effekt, dass eine
constexpr
Konstruktor hat, die auf die Klasse geben kann, Lesen Sie im C++ - StandardSo
constexpr
Konstruktoren bedeutet, dass statische Initialisierung durchgeführt werden kann und verwendet, wie this one sind möglich :Die bloße Tatsache, dass
test
ist ein literal Klasse bedeutet nicht, alle seine Instanzen werden Konstante Ausdrücke:Demo
Im obigen Beispiel wird die Instanz
a
wurde nicht deklariert als Konstanten so, obwohla
könnte einconstexpr
konstant, es ist nicht ein (damit es geändert werden kann).constexpr
Konstruktoren bei Klassen, arbeitete mit Anwender-definierte Literale und anschließend wurden als Literale. Meine Absicht zu reden, Literale hatte keine Erklärung im Körper der Antwort (+ einige ungeschickte Formulierung). Da gibt es keine Notwendigkeit zu verweisen, die habe ich entfernt, die schlecht formuliert Referenzen und hielt die literal-Klasse etwas. Irgendwelche Vorschläge ?Dem constexpr-Schlüsselwort durch meine Experimente in dieser Antwort mehr oder weniger weist den compiler, dass es in der Lage sein müssen, um statisch zu lösen alle codepaths gegeben, dass call. Das ist, zumindest jetzt (es scheint), muss alles deklariert werden constexpr zusammen, dass der Code, ansonsten schlägt es fehl. Zum Beispiel, in Ihrem code, die ersten constexpr Zuordnung zu b wird scheitern, wenn Sie nicht erklären, die Betreiber oder constexpr Konstruktor. Es scheint, dass die constexpr ist nur wirksam, wenn Sie die Zuweisung an eine variable, die deklariert werden constexpr, ansonsten scheint es nur dienen als ein Berater für den compiler, dass der Code optimiert werden kann über statische Auswertung, aber es ist nicht garantiert, es zu tun, wenn Sie nicht ausdrücklich anweisen, Sie mit einem constexpr variable Zuordnung.
Dass gesagt wird, es würde erscheinen, dass die Deklarierung eines constexpr Konstruktor hat keinen Einfluss unter normalen Umständen. Die Maschine code unten wurde hergestellt mit der folgenden Befehlszeile:
Also b Zuordnung erzeugt dieser code:
Jedoch, wenn Sie entfernen die constexpr-Erklärung über die b variable:
Erscheint es so gehandhabt, wie wenn der operator und Konstruktor nicht constexpr deklariert, aber dies ist eine situation, wo Sie sollten, konsultieren Sie die Einzelheiten zu Ihrem compiler, wirklich.