2010-12-09 9 views
3

Ich habe diesen Beispielcode:Ist dieser gültige C++ - Code standardgemäß?

struct A 
{ 
    bool test() const 
    { 
     return false; 
    } 
}; 


template <typename T = A> 
class Test 
{ 
public: 
    Test(const T& t = T()) : t_(t){} 

    void f() 
    { 
     if(t_.test()) 
     { 
      //Do something 
     } 
    } 
private: 
    const T& t_; 
}; 

int main() 
{ 
    Test<> a; 
    a.f(); 
} 

Grundsätzlich Ich mache mir Sorgen um den Konstruktor Test, wo ich eine konstante Referenz auf eine temporäre Variable bin zu speichern und in methof f verwenden. Bleibt der Verweis auf das temporäre Objekt innerhalb von f gültig?

+1

Ich denke - NEIN. Der Compiler kann (im allgemeinen Fall) nicht verfolgen, wohin die Referenz geht und ob sie persistent gespeichert wird. Aber am einfachsten ist es, eine Beispiel-App zu schreiben und zu sehen, was passiert. – valdo

+0

Es funktioniert auf VS2008, aber ich bin nicht davon überzeugt, dass es richtig ist. – Naveen

Antwort

7

Es wird nicht gültig bleiben. Das temporäre Objekt wird nach der Initialisierung a zerstört. Wenn Sie f aufrufen, rufen Sie ein undefiniertes Verhalten auf, indem Sie test aufrufen. Nur das Folgende ist gültig:

// Valid - both temporary objects are alive until after the 
// full expression has been evaluated. 
Test<>().f(); 
+0

Sind Sie sicher? 'Eine temporäre Bindung an ein Referenzelement im ctor-initializer (12.6.2) eines Konstruktors bleibt bestehen, bis der Konstruktor beendet wird. Eine temporäre Bindung an einen Referenzparameter in einem Funktionsaufruf (5.2.2) besteht bis zum Abschluss des vollständigen Ausdrucks, der den Aufruf enthält. "- dies ist der erste Fall, ich weiß nicht, ob es gültig ist ... – etarion

+0

@ etarion, 12.6.2 spricht über temporäre Ausdrücke. Ie Ausdrücke, die sich direkt auf ein temporäres Objekt beziehen. In diesem Fall initialisieren wir ein Referenzelement mit einem Ausdruck, der nicht direkt auf ein temporäres Objekt verweist, sondern durch eine Referenzbindung dazwischen. Dies ist nicht explizit dort drin, aber es ist gemeint. Also müssen Sie den zweiten Fall anwenden. –

+0

@etarion, um dies klarer zu machen. Betrachten Sie einige Beispiele: 'struct A {A & f() {return * this; }}; '. Die Absicht ist, dass 'A(). F(). F()' gültig ist, obwohl der Text sagt "Eine temporäre Bindung an den zurückgegebenen Wert in einer Rückgabeanweisung (6.6.3) bleibt bestehen, bis die Funktion beendet wird. " –