Hier ist ein Beispielcode:
%Vor%Sind Ausdrücke wie Foo (5) prvalues oder allgemeine rvalues? Ist die Tatsache, dass ich get_addr () für diese Ausdrücke aufrufen kann, eine Identität? Oder bedeutet die Tatsache, dass ich den Standard & amp; -Operator nicht anwenden kann (ich meine nicht überladen), dass sie keine Identität haben und daher prvalues sind?
Ist es auch fair zu sagen, dass die Veränderlichkeit des produzierten Wertes über den Ausdruck, der ihn erzeugt hat, orthogonal zu dieser Wertklassifikation ist?
Jeder Ausdruck ist einer und nur einer von:
Die Vereinigung von Ausdrücken, die lvalues und xvalues sind, werden kollektiv als glvalues bezeichnet.
Die Vereinigung von Ausdrücken, die xvalues und prvalues sind, werden gemeinsam als rvalues bezeichnet.
Somit sind xvalue-Ausdrücke sowohl als glvalues als auch als rvalues bekannt.
Das handliche Diagramm, das in Alf gefunden wurde, zeigt die Beziehung, die ich beschrieben habe, richtig mit Wörtern darüber, und wird auch in Abschnitt 3.10 der C ++ - Standards, Versionen C ++ 11 und höher gefunden.
Alles, was ich oben gesagt habe, vermute ich, dass das OP bereits wusste, nur aus dem Wortlaut des Titels dieser Frage.
Wissenswertes:
Bjarne Stroustrup erfand diese Klassifikation von Ausdrücken und dabei speicherte vielleicht der gesamte rvalue reference proposal ab kollabiert in der Kernarbeitsgruppe. Ich werde für immer dankbar sein.
Was ich hinzufügen möchte, ist eine Möglichkeit, für sich selbst herauszufinden, auf welche der drei untersten Klassifizierungskategorien sich ein Ausdruck bezieht: lvalue, xvalue oder prvalue.
%Vor%Die obige Funktion kann wie folgt verwendet werden:
%Vor%Und es wird die Frage dieses OP beantworten. Zum Beispiel:
%Vor%Für mich druckt:
%Vor%Ein Bereich, auf den Sie bei der Verwendung dieser Funktion achten sollten:
decltype(variable_name)
gibt den deklarierten Typ des Variablennamens an. Wenn Sie die Wertkategorie des Ausdrucks ermitteln möchten, wenn variable_name
verwendet wird (im Gegensatz zu dem deklarierten Typ), müssen Sie zusätzliche Klammern um (variable_name)
einfügen, wenn sie in decltype
verwendet werden. . Das ist:
ist der Typ des Ausdrucks variable_name
und nicht der deklarierte Typ von variable_name
.
Zum Beispiel gegeben:
%Vor%Dies wird fälschlicherweise ausgegeben:
%Vor% Fügen Sie die zusätzlichen Klammern zu decltype
hinzu:
um foo
von einem Typnamen in einen Ausdruck zu konvertieren. Jetzt ist die Ausgabe:
Wenn Sie nicht sicher sind, ob Sie Klammern hinzufügen müssen oder nicht, um die richtige Antwort zu erhalten, fügen Sie sie einfach hinzu. Wenn Sie sie hinzufügen, führt dies nicht zu einer falschen Antwort - es sei denn, Sie suchen nach dem deklarierten Typ einer Variablen und nicht nach dem Typ eines Ausdrucks. Und im letzteren Fall möchten Sie eine eng verwandte Funktion: type_name<T>()
.
Jeder Ausdruck in C ++ ist entweder ein lvalue oder ein rvalue . Daher fragen Sie nach den Klassifikationen, die rvalues sind. Schauen Sie sich hierzu die Abbildung des Klassifikationsbaums im C ++ 11-Standard §3.10 / 1 an.
Weitere Informationen (ohne sich mit dem Standard vertraut zu machen) finden Sie unter Was? rvalues, lvalues, ... .
Betreffend
"Sind Ausdrücke wie Foo (5) rvalues oder prvalue"
ein Pr-Wert ist ein R-Wert notwendig - denn es könnte nicht sehr gut ein L-Wert sein.
Ein prvalue "(" reiner "rvalue) ist ein rvalue, der kein xvalue ist, und ein xvalue ist" das Ergebnis bestimmter Arten von Ausdrücken, die rvalue-Referenzen "Ein Konstruktoraufruf erzeugt keine rvalue-Referenz, daher ist es kein xvalue. Also ist der rvalue ein prvalue, ein reiner rvalue.
Tags und Links c++ c++11 rvalue-reference rvalue xvalue