GOOGLE ADS

Montag, 25. April 2022

Ist ein prvalue dasselbe wie ein temporäres in C++17

Ich versuche zu wissen, ob a mit a in C ++ 17 prvalueidentisch ist. temporaryBetrachten Sie das folgende Beispiel,

//C++17 example
#include <iostream>
struct Custom
{
Custom()
{
std::cout<<"default constructor called"<<std::endl;
}
Custom(const Custom& var)
{
std::cout<<"copy constructor called"<<std::endl;
}
~Custom()
{
std::cout<<"destructor called"<<std::endl;
}
};
Custom func()
{
Custom temp;
return temp;//this will use copy constructor
}
int main() {
func();
}

Unter der Annahme, dass der obige Code mit -fno-elide-constructorsaktivierten Optionen ausgeführt wird, lautet meine Frage, ob der Prvalue, der als Kopie des tempin der Funktion benannten lokalen Objekts erstellt funcwird, mit einem temporären in C++17 identisch ist.

Ich habe gelesen, dass in C++17 ein Prvalue kein Objekt ist. Hier sagt zum Beispiel der Benutzer das

"Prvalues ​​sind keine Objekte (seit C++17)".

Ähnlich sagt hier der Benutzer

"Vor C++17 war der Prvalue bereits das Temporäre, worauf sich Ihr Zitat bezieht. Seit C++17 ist der Prvalue selbst kein Temporär..."

Aber das hat mich verwirrt, denn wenn ein Prvalue kein Objekt ist, was ist es dann? Ich meine, im obigen Beispiel tempwird eine Kopie von mit dem Kopierkonstruktor erstellt. Jetzt, vor C++17, ist diese Kopie ein temporäres Objekt, das ein Prvalue ist. Aber was ändert sich in C++17. Ich denke, dass wir immer noch einen Prvalue haben, der mit dem Kopierkonstruktor erstellt wird, und dass Prvalue in C++17 temporär ist, da er für eine begrenzte Dauer existiert.

PS: Ich kann falsch beschreiben, was tatsächlich passiert, also korrigieren Sie mich bitte, indem Sie erklären, was in C++17 passiert und wie es sich von C++14 unterscheidet. Ich frage auch, weil ich in SO-Beiträgen (ähnliche Beiträge) gelesen habe, dass im obigen Beispiel keine vorübergehende Beteiligung an C ++ 17 vorliegt, was ich nicht verstehe, wie dies möglich ist.


Lösung des Problems

Aber das hat mich verwirrt, denn wenn ein Prvalue kein Objekt ist, was ist es dann?

Ein Ausdruck, der zu einem Objekt werden kann.

Ich denke, dass wir immer noch einen Prvalue haben, der mit dem Kopierkonstruktor erstellt wird, und dass Prvalue in C++17 temporär ist, da er für eine begrenzte Dauer existiert.

Der Prvalue ist noch kein Objekt (oder hier anders gedacht ).

Lassen Sie uns Ihr Beispiel erweitern, indem Sie etwas verwenden func, um etwas zu initialisieren.

int main() {
auto obj = func();
}

objin mainund tempin funcsind "dasselbe Objekt". Es ist, als wäre funces stattdessen

void func(Custom * result) {
Custom & temp = *new(result) Custom;
}
int main() {
char storage[sizeof(Custom)];
Custom & obj = *reinterpret_cast<Custom *>(storage);
func(&obj);
obj.~Custom();
}

Oder beim -fno-elide-constructorsBelassen der Kopie von tempin den Rückgabewert:

void func(Custom * result) {
Custom temp;
new(result) Custom(temp);
}

Was sich zwischen C++14 zu C++17 geändert hat, ist, dass anstatt einer zulässigen Abweichung vom Verhalten der abstrakten Maschine die Definition der abstrakten Maschine geändert wurde, um dieses Verhalten aufzuweisen.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...