"named return values are no longer supported"



  • Hi(gh)!

    Für eine Klasse für dreidimensionale Vektoren ("Vec") will ich get-Funktionen schreiben - bekomme aber beim Kompilieren mit g++ 4.9.2 ständig die im Betreff genannte Fehlermeldung! Wie kann ich das vermeiden?

    Hier der Code:

    class Vec
    {
      private:
        double x;
        double y;
        double z;
      public:
        void set (double a, double b, double c);
        void print();
        double getx();
        double gety();
        double getz();
        friend Vec vcross(Vec v1, Vec v2);
        friend Vec vsubtract(Vec v1, Vec v2);
        friend Vec normal_vector(Vec v1, Vec v2, Vec v3);
    };
    
    void Vec::set (double a, double b, double c)
    {
      x = a;
      y = b;
      z = c;
    }
    
    void Vec::print()
    {
      cout << "<" << x << ", " << y << ", " << z << ">";
    }
    
    double Vec::getx() 
      return x;
    
    double Vec::gety()
      return y;
    
    double Vec::getz()
      return z;
    

    Bis bald im Khyberspace!

    Yadgar



  • @Yadgar
    Ich würds zuerst mal mit n paar geschweiften Klammern versuchen.


  • Mod

    Belli hat die Frage schon beantwortet, aber für alle anderen, die sich wie ich gerade fragen, über welches obskure Feature Yadgar hier gestolpert ist: https://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC106
    Also der Urvater der Copy Elision in Form einer Compilererweiterung.

    PS: @Yadgar : Wieso nutzt du kurz vor dem Jahr 2020 einen GCC 4.9.2?



  • Hui, wieder was gelernt! Was es nicht alles gibt bzw. gab!

    Ich habe noch eine andere Bemerkung:
    Ehrlich gesagt sind mir Namen wie getx, gety und getz zu undurchsichtig. Die ersten 3 Buchstaben sind irrelevant und die Information kommt dann ganz am Ende. Wenn es wenigstens getX, getY, getZ (oder für die Freunde des Underscores auch get_x, get_y, get_z) wäre - aber selbst da. Brauche ich bei einem 3d-Vector wirklich das "get"? Ich fände insbesondere hier einfach x(), y(), z() besser, da man schneller sieht, worum es eigentlich geht.

    Man könnte auch noch überlegen, ob man das Ding XYZVector oder CartesianVector3d nennt, um klar zu machen, dass intern kartesische Koordinaten verwendet werden und es sich um einen 3d-Vector handelt.

    Und vsubtract könnte man auch gut als operator- implementieren. Und für Skalarprodukt bietet sich operator* an. Einzig cross muss wohl eine Funktion sein. Für print bietet sich operator<< an.



  • @wob Finde ich auch. Ich denke auch zudem noch, dass lenght und setLenght fehlt.



  • @wob @titan99_ ich habe das als minimales, den Fehler produzierendes Beispiel aufgefasst.



  • @wob sagte in "named return values are no longer supported":

    Brauche ich bei einem 3d-Vector wirklich das "get"? I

    Nein, so für sich betrachtet sicherlich nicht. Aber dieses unschöne "get" hat auch Vorteile, wenn man sich darauf verlassen kann, dass alle öffentlichen Daten mit getXYZ zur Verfügung gestellt werden, nämlich dass man durch die IDE sofort alles zur Auswahl hat, sobald du "obj.get" eingetippt hast.
    Und Inkonsistenz ist halt auch blöd (hier weglassen, bei komplizierteren Sachen dann doch wieder). Also ich finde das "get" nicht schlecht.



  • Getter/Setter sind hier nun wirklich überflüssig wie ein Kropf.



  • @titan99_ sagte in "named return values are no longer supported":

    @wob Finde ich auch. Ich denke auch zudem noch, dass lenght und setLenght fehlt.

    Sorry, was sollen denn length zurückgeben bzw. was soll setLength machen? Habe so eine Funktion noch nie in Zusammenhang mit einem Vector gesehen.

    @manni66

    Getter/Setter sind hier nun wirklich überflüssig wie ein Kropf.

    Denke ich nicht. Stell dir mal vor, du möchtest diesen Vector durch einen 3d-Kugelkoordinaten-Vector ersetzen. Dann hast du auf einmal andere Member und x,y,z müssen über Funktionen berechnet werden. Damit du unabhängig von der internen Koordinatendarstellung bist, würde ich es wohl als Funktion machen.



  • @wob sagte in "named return values are no longer supported":

    Sorry, was sollen denn length zurückgeben bzw. was soll setLength machen? Habe so eine Funktion noch nie in Zusammenhang mit einem Vector gesehen.

    Fertige Klasse für Vektor. Soweit ich es in Erinnerung habe, bedeutet es in der glm lib etwas anderes. Gemeint ist damit aber die Länge eines Vektors, z.B. a=x2+y2+z2\left | \vec{a} \right | = \sqrt{x^2+y^2+z^2}



  • @wob sagte in "named return values are no longer supported":

    Denke ich nicht. Stell dir mal vor, du möchtest diesen Vector durch einen 3d-Kugelkoordinaten-Vector ersetzen.

    Dann verstecke ich die Konvertierung nicht hinter Getter/Setter. Stell dir vor, du willst anschliessend den Kugelkoordinatenvector durch einen Zylinderkoordinatenvector ersetzen.



  • Da wo ich zur Zeit arbeite, sind API-changes im Grunde nicht möglich (3x in den letzten über 20 Jahren). Aber das da Getter/Setter irgendwie wichtig gewesen wären, kann ich -soweit ich das beurteilen kann- nicht sagen. Wird trotzdem verpflichtend gemacht und stört mich auch nicht.



  • @titan99_ sagte in "named return values are no longer supported":

    Gemeint ist damit aber die Länge eines Vektors

    Achso. Das wäre aber ein eher unüblicher Name, davon würde ich sehr abraten. Da würde ich eher "magnitude" oder auch "magnitude2" vorschlagen, da man oft auf das Wurzelziehen verzichten kann. Oder man nennt das Ding L2Norm oder wie auch immer.
    Und das setLength finde ich noch merkwürdiger. (0,0,0).setLength(1) ist ja wohl ein bisschen undefiniert - sowas würde ich nicht einbauen. Dann eher ein "scale" zum Strecken. Wobei das einfach ein operator* ist.

    @manni66

    Dann verstecke ich die Konvertierung nicht hinter Getter/Setter. Stell dir vor, du willst anschliessend den Kugelkoordinatenvector durch einen Zylinderkoordinatenvector ersetzen.

    Sorry, ich verstehe dein Argument nicht. Das ist doch gar kein Problem. In allen 3 Fällen heißt es dann x(), wenn ich an die x-Koordinate will. Und außerdem kann ich in Fällen, in denen nicht sofort klar ist, welche interne Darstellung effizienter ist, einfach mal schnell ausprobieren, indem ich einen anderen Konstruktor nehme. Ansonsten muss ich nichts ändern. Ohne Funktion muss ich dann x durch x() oder theta durch theta() ersetzen.



  • @wob sagte in "named return values are no longer supported":

    Dann eher ein "scale" zum Strecken. Wobei das einfach ein operator* ist.

    scale kann ja schon vorkommen, dafür muss aber zuerst der Vektor normiert werden, wenn ich mich nicht täusche.

    @wob sagte in "named return values are no longer supported":

    da man oft auf das Wurzelziehen verzichten kann.

    Wie kann man das?


  • Mod

    @titan99_ sagte in "named return values are no longer supported":

    @wob sagte in "named return values are no longer supported":

    Dann eher ein "scale" zum Strecken. Wobei das einfach ein operator* ist.

    scale kann ja schon vorkommen, dafür muss aber zuerst der Vektor normiert werden, wenn ich mich nicht täusche.

    Das kommt drauf an, was man meint. Normalerweise würde man mit scale nicht das meinen, was du meinst.

    @wob sagte in "named return values are no longer supported":

    da man oft auf das Wurzelziehen verzichten kann.

    Wie kann man das?

    Was hast du denn vor mit der Länge? Zu 99% willst du sie doch mit anderen Längen vergleichen. Dann sparst du dir lieber das teure Wurzelziehen.



  • @wob sagte in "named return values are no longer supported":

    Ohne Funktion muss ich dann x durch x() oder theta durch theta() ersetzen.

    Nein. Ich verwende verschieden Vectorklassen.

    Konsequnterweise müsstest du ja schon in der ersten Implementierung alle möglichen Varianten anbieten.



  • @SeppJ sagte in "named return values are no longer supported":

    Was hast du denn vor mit der Länge?

    Vektor normieren?

    @SeppJ sagte in "named return values are no longer supported":

    Zu 99% willst du sie doch mit anderen Längen vergleichen. Dann sparst du dir lieber das teure Wurzelziehen.

    ?



  • Wenn sqrt(x) <= sqrt(y) (für nicht negative x und y) gilt,
    gilt auch x <= y

    und Wurzelziehen braucht Zeit.



  • @DirkB sagte in "named return values are no longer supported":

    und Wurzelziehen braucht Zeit.

    Also Quadratwurzeln haben soweit ich weiss eine hohe Konvergenzgeschwindigkeit mit dem Newtonverfahren. Also im Kopf habe ich irgendwie ca. 8 Iterationen für ein double, bin mir jetzt aber gar nicht sicher.


  • Mod

    @titan99_ sagte in "named return values are no longer supported":

    @SeppJ sagte in "named return values are no longer supported":

    Was hast du denn vor mit der Länge?

    Vektor normieren?

    Das ist ein Selbstzweck. Wozu willst du den Vektor normieren? Doch zu 99%, um ihn wieder mit anderen Vektoren zu vergleichen, z.B. um einen Winkel auszurechnen und mit anderen Winkeln zu vergleichen. Auch das geht wieder ohne Trigonometrie oder Wurzeln, wenn man sich im klaren ist, was man am Ende wirklich will.

    @titan99_ sagte in "named return values are no longer supported":

    @DirkB sagte in "named return values are no longer supported":

    und Wurzelziehen braucht Zeit.

    Also Quadratwurzeln haben soweit ich weiss eine hohe Konvergenzgeschwindigkeit mit dem Newtonverfahren. Also im Kopf habe ich irgendwie ca. 8 Iterationen für ein double, bin mir jetzt aber gar nicht sicher.

    Und? Bloß weil du die Wurzel in 20 µs berechnen kannst, ist das doch immer noch langsam, wenn die Alternative in 50x schneller fertig ist.


Log in to reply