Eine Frage zu rvalue Referenzen



  • Guten Morgen,

    ich habe eine Frage zu Rvalue Referenzen. Grundsätzlich ist mir die Bedeutung schon klar. Folgendes verwirrt mich jedoch:

    template<class T>
    T* address(T&& x) {
    	return &x;
    }
    
    char* p = address('A');
    *p = 'B';
    

    Da 'A' eine Konstante (und damit ein rvalue) ist, verwundert es mich, dass ich sie problemlos einem char* zuweisen kann.
    Vermuten tue ich lediglich, dass durch die rvalueness die Lebenszeit der Konstanten verlängert wird und daher auch danach noch gültig ist.

    Wenn dies jedoch möglich ist, stellt sich mir die Frage, ob die Deklaration oben mit "T const&&" noch einen Sinn ergeben würde oder nicht? Ist es überhaupt sinnvoll konstante rvalue Referenzen zu führen?

    Vorab schon mal vielen Dank für Aufklärung 😉



  • ...



  • CSpille schrieb:

    Was soll '&&' bewirken?

    Mein Compiler meckert verständlicherweise:

    Hast du auch C++0x angemacht?



  • CSpille schrieb:

    Was soll '&&' bewirken?

    && == Rvalue Reference. Kommt mit C++0x



  • ...



  • CSpille schrieb:

    Wofür braucht man sowas?

    Höhere Geschwindigkeiten, da unnötige Kopien reduziert/vermieden werden können.



  • FrEEzE2046 schrieb:

    ich habe eine Frage zu Rvalue Referenzen. Grundsätzlich ist mir die Bedeutung schon klar. Folgendes verwirrt mich jedoch:

    template<class T>
    T* address(T&& x) {
    	return &x;
    }
    
    char* p = address('A');
    *p = 'B';
    

    Da 'A' eine Konstante (und damit ein rvalue) ist, verwundert es mich, dass ich sie problemlos einem char* zuweisen kann.
    Vermuten tue ich lediglich, dass durch die rvalueness die Lebenszeit der Konstanten verlängert wird und daher auch danach noch gültig ist.

    Falsch vermutet. Dein Code ruft undefiniertes Verhalten hervor. Im Endeffekt ist es dasselbe Problem wie bei diesem Beispiel:

    template<class T>
    T const* address(T const& x) {
    	return &x;
    }
    
    char const* p = address('A');
    cout << *p; // OUCH!
    

    In beiden Fällen wird ein temporäres char-Objekt angelegt und mit 'A' initialisiert. Man merkt sich die Adresse auf das Objekt. Das Objekt wird wieder zerstört. Und danach wird ein ungültigen Zeiger verwendet.

    FrEEzE2046 schrieb:

    Wenn dies jedoch möglich ist, stellt sich mir die Frage, ob die Deklaration oben mit "T const&&" noch einen Sinn ergeben würde oder nicht? Ist es überhaupt sinnvoll konstante rvalue Referenzen zu führen?

    Nicht wirklich.

    Übrigens:

    template<class T>
    void foo(T&& x);
    
    int main() {
      int i = 23;
      foo(i);   // --> foo<int&>(int&);
      foo(i+1); // --> foo<int>(int&&);
    }
    

    ==> x ist je nach Argument entweder eine Rvalue- oder Lvalue-Referenz. Erklären kann man das mit der speziellen Deduktionsregel für T&& und dem Reference-Collapsing (&+& = &, &+&&=&, &&+&=&, &&+&&=&&).

    Übrigens 2: Eine benannte Rvalue-Referenz in einem Ausdruck ist ein Lvalue.

    kk



  • Von all den Artikeln, die ich über Rvalue-Referenzen gefunden habe, war nur einer aktuell genug (beschreibt die aktuellen Regeln):
    http://cpp-next.com/archive/2009/09/move-it-with-rvalue-references/
    (siehe auch den Artikel davor und die folgenden Artikel in der Serie)



  • @krümelkacker
    Danke, ich werde mir das mal anschauen.


Anmelden zum Antworten