Warum haben sich die Ausdruckstypen in C ++ zwischen den Versionen geändert?

13

Ich versuche, Ausdruckstypen von C ++ zu verstehen, und je mehr ich lese, desto verwirrter war ich, da ich den C ++ - Entwurf sehr schwer zu verdauen finde und daher andere Ressourcen bevorzuge, aber sie widersprechen sich entweder oder berücksichtigen nicht, dass die Wortlaut und Definition zwischen C ++ - Versionen ändern sich stark.

Im Folgenden beziehe ich mich auf folgende Entwürfe:

  • C ++ 11 [ n3690 ] (endgültiger Entwurf)
  • C ++ 17 [ n4659 ] (endgültiger Entwurf)
  • C ++ 20 [ n4835 ] (aktueller Entwurf)

C++11 3.10 LWerte und rWerte

... Ein Wert ("reiner" Wert) ist ein Wert, der kein x-Wert ist. [Beispiel: Das Ergebnis des Aufrufs einer Funktion, deren Rückgabetyp keine Referenz ist, ist ein Wert. Der Wert eines Literals wie 12, 7.3e5 oder true ist ebenfalls ein Wert. - Beispiel beenden]

C++17 3.10 LWerte und rWerte

... Ein Wert ist ein Ausdruck, dessen Auswertung ein Objekt oder ein Bitfeld initialisiert oder den Wert des Operanden eines Operators berechnet, der durch den Kontext angegeben wird, in dem er angezeigt wird.

C++20 7.2.1 Wertekategorien *

... Ein prvalue ist ein Ausdruck, dessen Auswertung ein Objekt oder ein Bitfeld initialisiert oder den Wert eines Operanden eines Operators berechnet, der durch den Kontext angegeben wird, in dem er angezeigt wird, oder einen Ausdruck vom Typ cv void.

Ich würde die Wortlautänderungen verstehen und einige Anpassungen vornehmen, aber für mich ändert sich die gesamte Definition. Kann mir jemand helfen, das zu verstehen? Warum wurde zum Beispiel der Satz entfernt, dass ein Wert ein r-Wert ist, der kein x-Wert ist? Oder warum wurde das hilfreiche Beispiel entfernt?

Daniel Stephens
quelle
3
Ich bin alle dafür, versionenspezifische Sprach-Tags zu verbieten. Bis auf genau diese Art von Fragen.
Neugieriger
" Berücksichtigen Sie nicht, dass sich der Wortlaut und die Definition zwischen C ++ - Versionen stark ändern. " Die Definition änderte sich jedoch nicht wirklich. Ziemlich viel Ausdruck, der in C ++ 11 ein Wert war, ist in C ++ 20 immer noch ein Wert.
Nicol Bolas
Wo ist der 'Widerspruch (Ion)' zwischen der Version? Was genau ist deine Frage?
Galigator
1
Entschuldigung für die C ++ 20-Änderung , aber ich hatte eine Inkonsistenz im Standard festgestellt.
Maggyero

Antworten:

5

Die ursprüngliche prvalue-Definition war nur eine Bezeichnung: Wir legen bestimmte r-Werte beiseite (nämlich solche, die keine x-Werte sind) und geben ihnen einen Namen. Es ist unmöglich, ihre Adresse zu nehmen, außer durch ungewöhnliche thisVerwendung (mehr oder weniger, weil sie vorübergehend sind), so dass bestimmte Freiheiten bei ihrer Erstellung und Verbreitung genommen werden können, ohne etwas zu brechen. (Siehe auch eine aktuelle Diskussion darüber, dass sie keine Identität haben.)

Die neue Definition besagt ausdrücklich, dass ein Wert eine Initialisierung ist, die darauf wartet, passiert zu werden: Sobald ein Zielobjekt dafür identifiziert wurde, wird es initialisiert. (Es ist wichtig zu beachten, dass die Initialisierung immer noch erfolgt, wenn der Wert erstellt wird, nur nicht dort, wo er sich befindet.) Dies wird als "obligatorische Kopierelision" bezeichnet, basierend auf der bereits üblichen äquivalenten Optimierung.

Für das Beispiel wurden die neuen Definitionen der Wertekategorien als so viel einfacher angesehen, dass weniger Beispiele benötigt wurden. Es gibt noch einen für x-Werte (die die subtilste Kategorie sind).

Davis Herring
quelle
Vielen Dank an Sie und die Kommentatoren! Das erklärt es ziemlich genau!
Daniel Stephens