int inkrement r-value



  • Hallo Leute,

    weiß einer von euch warum man (vom Sinn oder Unsinn dieses Vorgehens mal abgesehen) r-value ints, also z.B. so etwas wie

    int foo()
    {
      return 5;
    }
    
    int main() 
    {
      foo()++;
    }
    

    nicht mit "++" inkrementieren kann?

    Der Compiler sagt an dieser Stelle, dass nur l-values inkremtentiert werden könne, schreibt man sich jedoch selbst eine Klasse und überlädt das "++"

    class A
    {
      public:
      int val;
      A(int x) : val(x) {}
    
      A& operator++(int)
      {
        this->val++;
    
        return *this;
      }
    };
    
    A foo()
    {
      return A(0);
    }
    
    int main()
    {
      foo()++;
    
      return 0;
    }
    

    dann ist es möglich auch r-values zu inkrementieren.
    Wird die Exception evtl. Explizit in der Definition von "int" geworfen?

    Gruß



  • Ich habe keine ahnung, aber rate mal ins blaue:

    Vermutlich weil Zweiters auch nichts anders ist als

    operator++( foo(), int() );
    

    was natürlich gehen sollte.
    Und Ersters vom compiler anders beandelt wird weil POD.


  • Mod

    Ein rvalue heißt nicht unbedingt, dass das Objekt nicht veränderbar wäre. Manche eingebauten Operationen der eingebauten Datentypen brauchen hingegen echte lvalues. Insofern stimmt es, dass C++ hier nicht 100% konsistent erscheint.

    Vermutlich interessiert dich folgende Lektüre, auch wenn sie nur nochmal aussagt, was du selber schon festgestellt hast:
    http://accu.org/index.php/journals/227#ftn.d0e84



  • Gast007 schrieb:

    weiß einer von euch warum man [...] r-value ints, also z.B. so etwas wie

    int foo()
    {
      return 5;
    }
    
    int main() 
    {
      foo()++;
    }
    

    nicht mit "++" inkrementieren kann?

    Ja. Das, was foo zurück gibt, ist der Wert 5 und bezieht sich gar nicht auf ein Objekt (Im Sinne des Objektbegriffs von C++).

    Gast007 schrieb:

    Der Compiler sagt an dieser Stelle, dass nur l-values inkremtentiert werden könne, schreibt man sich jedoch selbst eine Klasse und überlädt das "++"

    class A
    {
      public:
      int val;
      A(int x) : val(x) {}
    
      A& operator++(int)
      {
        this->val++;
    
        return *this;
      }
    };
    
    A foo()
    {
      return A(0);
    }
    
    int main()
    {
      foo()++;
      return 0;
    }
    

    dann ist es möglich auch r-values zu inkrementieren.

    Da A ein Klassen-Typ ist, beziehen sich auch alle Rvalues (auch PRvalues) vom Typ A auf ein im Speicher lebendes Objekt. Elementfunktionen sind auch auf temporären Objekt aufrufbar, sofern die Qualifizierer es erlauben. Es steht hier dem ++ also nichts im Wege. Du kannst, wenn Du willst, es in C++2011 beschränken durch einen Ref-Qualifier:

    class A
    {
      ...
    
      A& operator++(int) &&;
    
      ...
    };
    

    so dass operator++ nur noch auf Lvalues aufrufbar wird. Aber soweit ich weiß, versteht das mit den Ref-Qualifizierern noch kein Compiler. Auf dem aktuellen Stand bin ich da aber auch nicht ...


Anmelden zum Antworten