Frage zu Referenzen



  • Mredl schrieb:

    Welche der folgenden Ausdrücke lässt sich kompilieren?

    Ersetze die Funktionen durch ihre Rückgabetypen und prüfe nach, ob der resultierende Ausdruck erlaubt ist. Nicht erlaubt ist eine Zuweisung zu einer Non-Const-Referenz ( int& ) von einem konstanten Wert ( const int ) bzw. von einer Referenz auf einen solchen ( const int& ) oder von einem Wert ( int ), wenn es sich bei letzterem um einen temporären Ausdruck handelt. Hinzufügen von const -Qualifizierern ist erlaubt, ebenso das Binden von temporären Objekten an Const-Referenzen. Wert-Kopien sind natürlich immer möglich, ungeachtet der Qualifizierer.

    const int a = 5;
    int b = 6;
    
    const int& ca = a;  // erlaubt
    const int& cb = b;  // erlaubt
    const int& cc = 5;  // erlaubt, temporärer Wert an Const-Referenz gebunden
    
    int& ra = a;        // verboten, a ist konstant
    int& rb = ca;       // verboten, ca zeigt auf konstanten Wert
    int& rc = cb;       // verboten, ungeachtet der Veränderbarkeit von b
    int& rd = 5;        // verboten, 5 ist temporär ("RValue")
    int& re = b;        // erlaubt
    
    const int& cd = ra; // erlaubt, man schränkt Zugriff mit const ein
    const int& ce = cd; // erlaubt
    

    Dein Beispiel könntest du so zerlegen (links des Pfeils steht der Typ des Ausdrucks, rechts der erwartete Typ für den nächst-äusseren Teilausdruck, also der Parametertyp der Funktion oder der Typ der zuzuweisenden Variable):

    5    // int  -> const int&, okay
              g(5)   // int& -> int,        okay
            f(g(5))  // int  -> int,        okay
    int i = f(g(5)); // Gesamtausdruck ist kompilierbar
    


  • vielen Dank, Nexus!
    eine konstruktive und hilfreiche Antwort genau das habe ich gebraucht. Du hast mir den Tag gerettet :D.



  • also nur zum Verständins:
    kommt nun
    int i = f(g(5)); //Ja
    int i = g(f(5)); //Nein
    f(5) = 7; //Nein
    g(5) = 7; //Ja
    ..dabei raus?



  • oder doch lieber
    ja
    ja
    ja
    nein



  • ok, jetzt bin ich verwirrt...



  • Ob die Ausdrücke kompilierbar sind, dürfte nicht allzu schwer festzustellen sein...



  • Was hindert Euch denn daran, es einfach auszuprobieren? Wenn dann der Compiler sich nicht so verhält, wie ihr es erwartet, dann könnt ihr ja nachfragen, wieso das so ist. Bis dahin, sehe ich nicht die Notwendigkeit, hier jemanden etwas vorzurechnen, was der Compiler für einen erledigen kann.



  • Stimmt...
    Compiler gibt es (teilweise) gratis zum Download

    int f(int);
    int& g(const int&);
    int main()
    {
            int i = f(g(5));
            int i2 = g(f(5));
            f(5) = 7; // <-- Zeile 7 !!!
            g(5) = 7;
            return 0;
    }
    

    test.cpp: In function ‘int main()’:
    test.cpp:7: error: lvalue required as left operand of assignment

    krümelkacker schrieb:

    Was hindert Euch denn daran, es einfach auszuprobieren? Wenn dann der Compiler sich nicht so verhält, wie ihr es erwartet, dann könnt ihr ja nachfragen, wieso das so ist.

    👍



  • sorry wenn ich euch auf die nerven geh(morgen muss ich das alles können o.o), aber wenn ich das in compiler eingeb, kommt auch ne "Linked error undefined reference to g(int const&)" und "Linked error undefined reference to f(int)" Meldung

    "int f(int);
    int& g(const int&);
    int main()
    {
    int i = f(g(5));
    return 0;
    }



  • Mredl schrieb:

    sorry wenn ich euch auf die nerven geh(morgen muss ich das alles können o.o), aber wenn ich das in compiler eingeb, kommt auch ne "Linked error undefined reference to g(int const&)" und "Linked error undefined reference to f(int)" Meldung

    kein Problem...

    Dein Linker sucht nach der Implementierung der Funktion und die findet er nicht.
    Deinem Compiler reicht die Vorwärtsdeklaration und er 'denkt sich',
    wenn er das Programm erstellen will muss er die noch irgendwie zur Verfügung
    stellen und darum kümmert sich schon der Linker.



  • ok danke. das hatte mich noch irritiert


Anmelden zum Antworten