Frage

Ist es möglich, ändern Sie das temporäre Objekt und übergeben Sie es als argument?

struct Foo {    
   Foo& ref() { return *this; }
   Foo& operator--() { /*do something*/; return *this; }
   // another members
};
Foo getfoo() { return Foo(); } // return Foo() for example or something else
void func_val(Foo x) {}
void func_ref(const Foo & x) {}

int main() {
   func_val(--getfoo());     // #1 OK?
   func_ref(getfoo());       // #2 OK?
   func_ref(getfoo().ref()); // #3 OK?
   // the following line is a real example 
   //    using --vector.end() instead of --getfoo()
   func_ref(--getfoo());     // #4 OK? 

   const Foo & xref = --getfoo(); //  Does const extend the lifetime ?
   func_ref(xref);     // #5 OK? 
   func_val(xref);     // #6 OK? 

}

Es ist bekannt, dass die Zuweisung einer temporären Objekt, um die const-Referenz-verlängert die Lebensdauer von diese temporäre Objekt.Und was ist mit der #4 und #5 Linien meinem code?Ist es wahr, dass Referenz-x ist immer gültig, in der die Funktion func_ref?Die Sache ist, dass Betreiber-- gibt einen Hinweis, und der compiler sieht keinen Zusammenhang zwischen dieser Referenz-und der vorübergehenden wir erstellt haben.

War es hilfreich?

Lösung

func_val(--getfoo());     // #1 OK?

Ja, OK.Die operator-- ist eine member-Funktion, die aufgerufen wird, und gibt sich selbst (und lvalue Bezugnahme auf sich selbst).Das Objekt wird dann kopiert und in die parameter der func_val.Beachten Sie, dass return-Wert-Optimierung ist nicht erlaubt zu gelten, da die vorübergehende erstellt von getfoo() zuvor war an eine Referenz.

func_ref(getfoo());       // #2 OK?

Ja, OK.Der Anruf getfoo() gibt eine temporäre, die gebunden ist an die const-Referenz.Ein copy-Konstruktor ist erforderlich, aber die nennen es können optimiert werden durch die Umsetzung.Die vorübergehende besteht bis zum Ende des full-Ausdruck mit dem Aufruf func_ref (der ganze Ausdruck hier).

func_ref(getfoo().ref());

Ja, OK.Kein copy-Konstruktor erforderlich, da wir binden die const-Referenz nicht zu einer vorübergehenden, sondern um die lvalue repräsentiert das Objekt selbst.

// the following line is a real example 
//    using --vector.end() instead of --getfoo()

Das ist nicht erforderlich, um zu arbeiten.Denken Sie an eine situation, wo vector.end() gibt eine T* (erlaubt).Sie sind nicht erlaubt zu ändern rvalues of non-class type, so in diesem Fall, das wäre schlecht ausgebildet.

func_ref(--getfoo()); 

Ja, OK.Das argument wird ausgewertet, wie in #1, aber die resultierende lvalue ist direkt übergeben und die const-Referenz gebunden ist.In diesem Sinne ist es gleich #3 (außer für die Dekrement-Nebenwirkung).

const Foo & xref = --getfoo();

Die Standard-Formulierung ist nicht ganz klar.Sicherlich will nur verlängern Lebensdauer von Objekten noch nicht an eine Referenz.Aber in unserem Fall, --getfoo() ergibt einen lvalue bezieht sich auf ein temporäres Objekt, das zuvor gebunden an eine Referenz.Es kann sein, lohnt sich die Einreichung einer Fehlerbericht an den Ausschuss (darf ich das auch übersehen haben, die Formulierung, erfordert das temporäre Objekt nicht begrenzt werden, um eine Referenz noch).

In jedem Fall, das beabsichtigte Verhalten ist es, zu zerstören die temporäre, dass die Ergebnisse aus getfoo() am Ende der Initialisierung xref, so xref wird eine baumelnde Referenz.

Die Sache ist, dass Betreiber-- gibt einen Hinweis, und der compiler sieht keinen Zusammenhang zwischen dieser Referenz-und der vorübergehenden wir erstellt haben.

Genau (aber gilt nur für die Initialisierung der xref das wird verrückt.In allen anderen Fällen das gewünschte Verhalten, die Sie wollen (oder was ich glaube, was du willst) ist erreicht).

Andere Tipps

Provisorien leben immer für die gesamte Lebensdauer des voll Ausdruck, in dem sie ohnehin geschaffen sind. Daher wurde in der Ausdrucksanweisung func_val(--getfoo());, die Lebensdauer der temporären durch den getfoo() Ausdruck zurückgegeben keine Erweiterung benötigt. Die Anweisung wird erst am Ende nach func_val() zurückgekehrt war.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top