matrix double multiplikation als operator



  • Kurze Antwort: Eine Referenz kannst du nur dann zurückgeben, wenn das referenzierte Objekt lange genug überlebt. Und dein Operator wird vermutlich ein lokales Objekt zurückgeben - und das überlebt nicht lange genug um etwas damit machen zu können.
    (tja, mitunter sind Kopien unvermeidlich)



  • matrix &operator*(double factor, const matrix &rhs) const{
       matrix ergebnis;//lokale variable
      for(...{
         for(...{
            ergebnis[j][i]=rhs[j][i]*factor;
      return ergebnis;//referenz auf lokale varieble rausgeben
    }//lokale variable stirbt hier! die referenz zeigt auf toten speicher
    

    Kommst nicht um die Kopie rum. Also im Prinzip nicht.
    Aber faktisch doch!!!

    Matrix c=5*a;//hier zaubert ein schklauer compiler normalerweise und schreibt das ergebnis gleich nach c rein
    

    http://en.wikipedia.org/wiki/Return_value_optimization und NRVO



  • CStoll schrieb:

    EOutOfResources schrieb:

    @CStoll Rückgabe nicht const ?

    Wenn du unbedingt darauf bestehst, kann man das natürlich machen 😉

    Würde ich nicht. Bringt nicht wirklich Vorteile.



  • CStoll schrieb:

    (tja, mitunter sind Kopien unvermeidlich)

    Außer man heißt uBLAS oder Blitz++ 😉



  • otze schrieb:

    CStoll schrieb:

    (tja, mitunter sind Kopien unvermeidlich)

    Außer man heißt uBLAS oder Blitz++ 😉

    Zumindest uBLAS hat eine unbrachbare Syntax, wofür das u wohl auch steht.



  • Nexus schrieb:

    Würde ich nicht. Bringt nicht wirklich Vorteile.

    Es kann Fehler verhindern.



  • EOutOfResources schrieb:

    Nexus schrieb:

    Würde ich nicht. Bringt nicht wirklich Vorteile.

    Es kann Fehler verhindern.

    Beispiel?
    Mir fällt gerade (vermutlich wegen Gurkenmangels) nur Mist ein wie

    c=(a+b)*=2;//gäbe mit const einen compilerfehler
    


  • volkard schrieb:

    Beispiel?

    //Rückgabe nicht const:
    if(a * b = c)
    {
      //Hoppla, ich wollte vergleichen aber es kompiliert
    }
    //Rückgabe const:
    if(a * b = c)
    {
      //Hoppla, ich wollte vergleichen aber Compilefehler
    }
    

    Scott Meyers vertritt die selbe Meinung in "Effektiv C++".



  • EOutOfResources schrieb:

    //Rückgabe nicht const:
    if(a * b = c)
    {
      //Hoppla, ich wollte vergleichen aber es kompiliert
    }
    

    Hier spuckt dir jeder vernünftige Compiler bei einer vernünftigen Warnungsstufe eine Warnung aus, dass du eine Zuweisung in der Bedingung stehen hast. Und als vernünftiger Entwickler siehst du natürlich zu, dass dein Code warnungsfrei compiliert und behebst das auch ohne const Rückgabe.



  • Zur Erheiterung: Dieser Fehler fliegt, wenn ich matrix keinen operator bool schenke bei if(a*b=c):

    C:\src\research\tmpcpp\main.cpp||In function 'int main()':|
    C:\src\research\tmpcpp\main.cpp|7|error: could not convert '((operator*((a, matrix()), (b, matrix())), ((const matrix&)((const matrix*)(& c)))), operator*((a, matrix()), (b, matrix())))' to 'bool'|
    ||=== Build finished: 1 errors, 0 warnings ===|
    

    Im Prinzip hast Du wohl recht.
    Ich würde auch vorschlagen, darüber nachzudenken, noch weiter zu gehen, und den Zuweisungsoperator void zurückgeben zu lassen. Dann hat sich das const in diesem Beispiel von selbst erledigt.


  • Mod

    volkard schrieb:

    EOutOfResources schrieb:

    Nexus schrieb:

    Würde ich nicht. Bringt nicht wirklich Vorteile.

    Es kann Fehler verhindern.

    Beispiel?
    Mir fällt gerade (vermutlich wegen Gurkenmangels) nur Mist ein wie

    c=(a+b)*=2;//gäbe mit const einen compilerfehler
    
    c=a+b;
    

    Ist schon das perfekte Beispiel warum const Mist ist. Ohne const kann eine move-Zuweisung benutzt werden. Mit const müssen wir kopieren.


Anmelden zum Antworten