Frage bzgl. L-und R-Wert-Referenzen und Operaten



  • Hi,
    ich haette eine Frage bzgl. L und R Wert Referenzen.
    Wenn ich z.B einen + Operator fuer Strings schreibe mit dem Rückgabewert string& und dieser nichts anderes tut, als dafür zu sorgen, dass aus "hi"+"hallo" "hihallo" wird und ich folgendes mache:
    s3 = s1+s2
    dann waere s1+s2 ein R oder ein L Wert und warum?
    Meine Vermutung ist, dass ein L-Wert zurückgegeben wird, der aber dadurch, dass er ja nur temporär existieren würde, denn s1+s2 hat keine eigene Speicheradresse, über die sie angesprochen werden könnten zum R-Wert wird?
    Liege ich damit richtig?



  • Bei einem operator+ willst du keine Referenz zurückgeben.



  • @spiri Angenommen ich wuerde aber eine Referenz zurueckgeben, dann waere s1+s2 doch trotzdem ein R-Wert oder nicht? Denn wuerde ich s1+s2 nicht s3 zuweisen, dann waeren sie ja so gesagt danach einfach "weg", oder nicht?



  • @tes32 sagte in Frage bzgl. L-und R-Wert-Referenzen und Operaten:

    Angenommen ich wuerde aber eine Referenz zurueckgeben

    Erkläre warum und eine referenz worauf.



  • MFC?



  • @manni66 sagte in Frage bzgl. L-und R-Wert-Referenzen und Operaten:

    MFC?

    Mit Freuntlitschen Crüßen?

    // edit: <rant>Das ist genau der Krampf der passiert seit alles möglitsche eine Unterkategorie von C++ ist anstatt ein Forum für GUI-Frameworks zu haben.</rant>



  • @Swordfish Wenn ich einen + operator haette mit dem rueckgabewert string& und ich dann damit zwei strings addoeren wuerde. S3 = s1+ s2, dann waere s1+s2 in dem falle ein r wert, da, wenn ich s1+s2 einfach so in den code schreiben wuerde, s1+s2 keine speicheradresse haette und nur kurz im speicher waere und im fall von s3=s1+s2 s1+s2 ein r wert waere obwohl der plus operator einen l wert referenz rueckgibt, ist das richtig?



  • Eine Expression aus einer Funktion die eine Referenz zurückgibt ist ein lvalue. Ganz egal, wo sie steht.



  • @Swordfish aber wenn der compiler aus der Operator Methode/Funktion rausspringt, dann muss er ja zwangslaeufig die zurückgegebene String& Referenz im Speicher halten, sodass diese doch in dem Falle s3 = s1+s2 ein R-Wert waere, oder nicht? Denn wenn ich eine funktion haette Bsp:
    func(int a, int b){
    return a+b;
    }
    diese rufe ich in der main auf
    int main(){
    int c = func(4,4);
    return 0;
    }
    dann ist es doch so, dass der Rueckgabewert in diesem Fall die Zahl 8(4+4) doch ein R-Wert waere, der nur kurzfristig im Speicher gehalten wird, oder irre ich da?



  • Das hat damit erstmal nichts zu tun. Wenn eine Funktion eine Referenz zurückgibt, kannst du das durchaus als lvalue benutzen (bzw. auf der linken Seite einer Zuweisung). Ob das dann funktioniert, ist eine andere Frage.



  • @tes32 "muss im Speicher behalten" ... hör bitte auf so zu denken. Ein Compiler muss einen feuchten kehrricht. In deinem Beispiel darf er auch dein c direkt mit 8 initialisieren ohne func() jemals aufzurufen (davon ausgehend, daß c später noch verwendet wird. Wenn nicht gibts eventuell gar kein c.). Wie eine Expression verwendet wird bestimmt nicht, von welcher Value-Kategorie sie ist.



  • @Swordfish koenntest du mir dann bitte ein Beispiel geben, wann genau ein R-Wert Value entsteht?
    Denn das Standartbeispiel ist ja meistens int a = 4. Dann sagen die Lehrbuecher, 4 ist ein R-Wert. Wie erzeuge ich denn einen R-Wert bei z.B Objekten, wenn nicht ueber Funktionen?



  • Da du so auf funktionen und deren Rückgabetyp fixiert bist:

    int foo() { return 42; }
    
    // ...
    
    foo(); // ist ein rvalue. genauer ein prvalue.
    

    Guckst du bitte http://www.stroustrup.com/terminology.pdf



  • @Swordfish Ok, der Aufruf von foo(); ist ein r bzw pr value. Ich habe folgenden Beispielcode
    #include "VektorClass.h"
    VektorClass& func(VektorClass& a){
    return a;
    }
    int main(){
    VektorClass b;
    VektorClass &c = b;
    VektorClass{func(c)};
    return 0;
    }

    Dann Frage ich mich wieso VektorClass{func(c)}; nicht den Verschiebekonstruktor aufruft bzw. warum func(c) keinen r Wert liefert?
    Denn natürlich ist der Rückgabewert ein LValue, aber es ist ja namenlos(nach stroustrup also (Im:
    does not have identity and can be moved from)) und ruft den Copy Konstruktor auf? Und einen prValue wuerde dann func(c); erezugen? Wie ist es denn dann möglich in meinem Beispiel den Verschiebekonstruktor aufzurufen? Dieser erwartet ja VektorClass(Vektor&& a)?



  • Schau mal im C++-Standard nach, Kapitel 3.10 (bei C++14) oder 6.10 (C++17):

    (aus C++14)

    An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment
    expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated
    with an object.



  • @tes32 Würdest du bitte Code in deinen Beiträgen ordentlich formatieren? Danke.

    Zu deinem Beispiel: Da brauchen wir garnichtmal von irgendwelchen Value-Kategorien reden/wissen um zu schnallen, warum da nicht gemoved werden kann. Das was deine func() zurückgibt ist eine Referenz auf b. b kann nicht einfach so aufhören zu existieren indem von b gemoved würde.



  • @Swordfish

    #include "VektorClass.h"
    VektorClass func(VektorClass& a){
    	return a;
    }
    int main(){
    	VektorClass b;
    	VektorClass &&c = func(b);
    	return 0;
    }
    
    
    Hier wuerde es sich dann aber um einen rvalue handeln, da dieses zerstoert werden kann? Und bei Operatoren die z.B ein VektorClass& zurueckgeben, da waere es dann doch auch das gleiche, oder nicht?


  • @wob Vielen Dank, haettest du vllt. einen Link? Oder meinst du die Website
    https://isocpp.org/std/the-standard



  • Der letzte Standard Draft: http://eel.is/c++draft/basic.lval

    Hier wuerde es sich dann aber um einen rvalue handeln, da dieses zerstoert werden kann?

    Wenn du das gelesen hast, hörst du bitte auf solche sachen zu sagen.

    Und bei Operatoren die z.B ein VektorClass& zurueckgeben, da waere es dann doch auch das gleiche, oder nicht?

    Nein, es ist bezüglich der Value-Kategorie ein Unterschied, ob eine Funktion eine Referenz oder einen Value-Typ zurückgibt.



  • @Swordfish

    #include "VektorClass.h"
    VektorClass func(VektorClass& a){
       return a;
    }
    int main(){
       VektorClass b;
       VektorClass &&c = func(b);
       return 0;
    }
    

    Nach Standard bin ich mir nicht sicher ob func(b) jetzt
    1.1 A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
    ist, da der glvalue eine expression ist dessen valuation die Identitaet des Objekts bestimmt, dürfte hier nicht der Fall sein.
    oder
    1.2
    A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of an operand of an operator, as specified by the context in which it appears.
    Muesste der Fall sein, da func(b);
    mit

    VektorClass &&c = func(b);
    

    &&c intilisiert bzw. ein anderes Objekt intialisieren koennte, ist das so richtig?

    #include "VektorClass.h"
    VektorClass& func(VektorClass& a){
    	return a;
    }
    int main(){
    	VektorClass b;
    	VektorClass &c = b;
            VektorClass d {func(c)};
    	return 0;
    }
    

    Tritt hier

    4

    [ Note: An expression is an xvalue if it is:

    (4.1)
    the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type ([expr.call]),
    

    auf?
    Aber mein return Typ ist eine lvalue Referenz und damit ist das ausgeschlossen. Ich weiß nicht um welchen Punkt es sich hier nach Standard handelt 😕
    Was ich mir noch vorstellen koennte:
    (1.1)
    A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
    Die Auswertung er Funktion fuehrt ja zu der Identitaet meines Objectes d.
    (1.3)
    An xvalue is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime).
    (1.4)
    An lvalue is a glvalue that is not an xvalue.
    Jetzt wuerde ich sagen es gilt 1.3 und somit ist es ein xvalue, denn das obejt hat das Ende seiner Lebenszeit, dadurch das es zurückgegeben wird, erreicht.


Anmelden zum Antworten