rvalue reference



  • A&& i = { A&& a( A() ), t };
    

    Was bitte soll denn das sein?
    Edit: Oh, tut mir Leid, das ist ja Pseudocode.



  • Sone schrieb:

    Nein, aber static_cast ist der Rückgabewert von move .

    Das spielt aber keine Rolle!!
    Wäre static_cast<T&&>(x) definiert als "rvalue-referenz auf x" würde sich static_cast anders verhalten als std::move, weil std::move eine Funktion ist und static_cast nicht. Ich gebs auf mit dir zu diskutieren.



  • Wäre static_cast<T&&>(x) definiert als "rvalue-referenz auf x" würde sich static_cast anders verhalten als std::move, weil std::move eine Funktion ist und static_cast nicht.

    ---
    Es verhält sich ja deswegen gleich, weil der Wert eines Funktionsaufrufs derselbe ist, wie der des zurückgegebenen Wertes. Und move ist genauso definiert, dass es static_cast<T&&>(t) zurückgibt.
    Daher hat move in dieser Hinsicht immer denselben Effekt wie static_cast<T&&>(t) .

    Und damit hatte ich völlig Recht:

    Effektiv steht da

    int&& j = static_cast<int&&>(0);
    

    Ich gebs auf mit dir zu diskutieren.

    Ich nicht, aber wenn du müde bist...



  • Irgendwie zweifel ich an einem Sprachstandard, den man fast wortwörtlich auswendig lernen muss, dmait man das Verhalten der Sprache interpretieren kann.



  • otze schrieb:

    Irgendwie zweifel ich an einem Sprachstandard, den man fast wortwörtlich auswendig lernen muss, dmait man das Verhalten der Sprache interpretieren kann.

    Deswegen ist C++ nur für die Verrückten.



  • Sone schrieb:

    Und damit hatte ich völlig Recht:

    Effektiv steht da

    int&& j = static_cast<int&&>(0);
    

    Jo, bis dahin schon.

    Sone schrieb:

    Und das ist wohldefiniertes Verhalten. Auch für Klassen. Auch hier wird die Lebenszeit verlängert.

    Das war hingegen falsch. Falls j weiter verwendet wird hat man UB.



  • Ja, das stimmt. 🙂
    Signatur angepasst.



  • Sone schrieb:

    otze schrieb:

    Irgendwie zweifel ich an einem Sprachstandard, den man fast wortwörtlich auswendig lernen muss, dmait man das Verhalten der Sprache interpretieren kann.

    Deswegen ist C++ nur für die Verrückten.

    03 war noch lange nicht so schlimm wie 11.



  • otze schrieb:

    03 war noch lange nicht so schlimm wie 11.

    Gilt genauso für C++03.

    struct A
    {
      A(){std::cout << "C";}
      ~A(){std::cout << "D";}
    };
    
    A const& hi(A const& a)
    {
      return a;
    }
    
    int main()
    {
      {
        A const& i = hi(A());
        std::cout << " hi ";
      }
      std::cout << "\n--\n";
      {
        A const& i = static_cast<A const&>(A());
        std::cout << " hi ";
      }
    }
    
    /* Ausgabe:
    CD hi
    --
    C hi D
    */
    

    Ich verstehs aber immer noch nicht. Damit wäre nämlich static_cast tatsächlich anders als move.



  • Da wird wohl einfach der Compiler falsch liegen. Genau wie selbst die neuste veröffentlichte Variante des GCCs nicht standardkonform ist. Ich würde es auf 4.9 testen, bin aber zu faul um umzubooten.

    Hast du obiges Beispiel auf Clang getestet?

    03 war noch lange nicht so schlimm wie 11.

    Auch C++03 hatte seine Hardcore-Teile.



  • Sone schrieb:

    Hast du obiges Beispiel auf Clang getestet?

    Auf g++ 4.9 sowie auf clang 3.4. Verhält sich aber auch auf älteren Versionen so.



  • Wenn das tatsächlich nicht konform ist, dann müsste man beiden Compilern ein Ticket schreiben.



  • Sone schrieb:

    Auch C++03 hatte seine Hardcore-Teile.

    Aber irgendwie wurden das mit C++11 nur mehr, nicht weniger. Dieser ganze RValuee kram ist ohne Standard lesen nicht ordentlich erklärbar, weil es da echt um details geht.



  • otze schrieb:

    Sone schrieb:

    Auch C++03 hatte seine Hardcore-Teile.

    Aber irgendwie wurden das mit C++11 nur mehr, nicht weniger.

    Richtig, also wie ich sagte, C++ ist für Verrückte. Ich dachte zuerst, 10-15 Jahre? Die spinnen! Das schaff' ich in Fünf.

    Jetzt bin ich genau zweieinhalb dabei, und es gibt kein Ende. Nein, desto mehr ich um mich sehe, öffnen sich mir die Augen. Mit C++14 und 17 wird es noch ein wenig mehr. Dabei ist C++11's Move-Semantik an sich doch so intuitiv...

    Dieser ganze RValuee kram ist ohne Standard lesen nicht ordentlich erklärbar, weil es da echt um details geht.

    Deswegen strenge ich mich auch so an, alles durch den Standard zu erklären. Nur ist das so frickelig. Da ist Sutter bspw. eine gute Quelle. Denn wer ist besser als der, der weiß, was die Paragraphen eigentlich bedeuten?

    Oder camper, der Überflieger.



  • Sone schrieb:

    Deswegen strenge ich mich auch so an, alles durch den Standard zu erklären.

    Das machts aber nicht besser, weil man dann den Standardtext verstehen muss. Und dann redet man auf einmal über l,r,pr,xl,gl values. wtf?!?



  • otze schrieb:

    Und dann redet man auf einmal über l,r,pr,xl,gl values. wtf?!?

    Das ist ja noch gar nichts, und die Begriffe sind doch eigentlich selbst redend. Es gibt drei Grundarten von Ausdrücken - lvalues: Das sind alle Objekte/Referenzen mit Namen und alle lvalue-Referenzen,
    xvalues sind alle unbenannten rvalue Referenzen und Ausdrücke damit (wie Member von denen usw.),
    und prvalues sind alle Namenlosen Objekte (bspw. Temporaries).

    Also ist die Faustregel: Alles mit einem Namen resultiert in einem lvalue als Ausdruck, und alles unbenannte außer lvalue-Referenzen ist ein rvalue.

    Und bei deiner Aufzählung muss das l vom x weg.



  • Sone schrieb:

    die Begriffe sind doch eigentlich selbst redend.

    Aha

    lvalues: Das sind alle Objekte/Referenzen mit Namen und alle lvalue-Referenzen,

    Also sind enum-Konstanten lvalues.

    xvalues sind alle unbenannten rvalue Referenzen und Ausdrücke damit (wie Member von denen usw.),

    Wie soll man das verstehen ohne zu wissen, was ein rvalue ist?
    Also:

    string s;
    return s; // <-- s ist kein xvalue
    

    prvalues sind alle Namenlosen Objekte (bspw. Temporaries).

    Ok, also

    string s = "...";
    s[0] // <- prvalue
    

    Und ich wäre immer noch daran interessiert, die Ausgabe http://ideone.com/rsHZgs zu verstehen.



  • Also sind enum-Konstanten lvalues.

    Enumeratoren sind keine Objekte.

    Wie soll man das verstehen ohne zu wissen, was ein rvalue ist?

    Gar nicht. Habe ich das behauptet?

    string s;
    return s; // <-- s ist kein xvalue
    

    Die Aussage ist natürlich Blödsinn, und kann aus meinen soweit ich sehe nicht abgeleitet werden. s ist ein Objekt mit Namen. Daher ist der Ausdruck mit seinem Namen ein lvalue.

    zjraw schrieb:

    prvalues sind alle Namenlosen Objekte (bspw. Temporaries).

    Ok, also

    string s = "...";
    s[0] // <- prvalue
    

    Gut, hier bin ich zu pauschal gewesen.
    Aber ich habe mich explizit auf lvalue Referenzen als lvalues bezogen. Das beinhaltet Funktionen, die lvalue Referenzen zurückgeben. Reicht das nicht als
    Fallunterscheidung?

    Und das ist alles noch relativ einfach. Auch wenn ich das zu verallgemeinern versucht habe, ist es an sich wirklich einfach. Da gibt es noch viel schwierigeres.



  • Sone schrieb:

    die Begriffe sind doch eigentlich selbst redend.

    lvalues: Das sind alle Objekte/Referenzen mit Namen und alle lvalue-Referenzen

    Aha. Der Name kommt aber daher, dass l-values links in einer Zuweisung stehen.
    Trotzdem kann ich auch einem temporary Dinge zuweisen, wenn ich mag und das Ding einen entsprechend überladenen op= hat. Das macht das temporary aber noch nicht zu einem l-value. Also ist der Name nicht selbstredent.

    //edit und welche namentliche Bedeutung pr, gl oder x haben soll...naja.



  • otze schrieb:

    Aha. Der Name kommt aber daher, dass l-values links in einer Zuweisung stehen.
    Trotzdem kann ich auch einem temporary Dinge zuweisen, wenn ich mag und das Ding einen entsprechend überladenen op= hat. Das macht das temporary aber noch nicht zu einem l-value. Also ist der Name nicht selbstredent.

    Nein, das ist er leider tatsächlich nicht, auf den zweiten Blick. 🙂

    //edit und welche namentliche Bedeutung pr, gl oder x haben soll...naja.

    Das ist doch alles im Standard erklärt!
    pure rvalues, generalized lvalues und expiring values. Alles gut gewählt.


Anmelden zum Antworten