Frage zu "return"



  • Die erinnerung schrieb:

    Also doch richtig!

    Nene, das hat erstmal nichts mit dem Typ zu tun. Funktortypen setzen sich u.U. aus mehr zusammen als nur aus einer Funktionssignatur, darauf kannste dich also nicht verlassen. Zudem hast du in Zeile 12 noch was vergessen. 😉



  • Dann halt so :p

    template <typename T, typename Functor, typename Functor2>
    T newt(T x_0, Functor fct, Functor2 der)
    {
        T x_n = 0, y_test = fct(x_0);
    
        if(abs(y_test) < 1.e-30)
        {
            return x_0;
        }
        x_n = x_0 - fct(x_0)/der(x_0);
    
        return newt(x_n);
    }
    

    Es war nicht Zeile 12, sondern Zeile 4. Also ganz blöd bin ich auch nicht!

    Wobei ich immernoch die Version nehmen würde. Da ist nämlich sichergestellt, dass der Datentyp stimmt!

    template <typename T>
    T newt(T x_0, T (*fct)(T), T (*der)(T))
    {
        T x_n = 0, y_test = fct(x_0);
    
        if(abs(y_test) < 1.e-30)
        {
            return x_0;
        }
        x_n = x_0 - fct(x_0)/der(x_0);
    
        return newt(x_n);
    }
    


  • Die erinnerung schrieb:

    Es war nicht Zeile 12, sondern Zeile 4. Also ganz blöd bin ich auch nicht!

    Guck dir Zeile 12 noch mal genau an.

    Die erinnerung schrieb:

    Wobei ich immernoch die Version nehmen würde. Da ist nämlich sichergestellt, dass der Datentyp stimmt!

    Ja? Mit T = std::string? Nene, solange C++ keine Concepts anbietet kannste das vergessen. (Manchmal kann man vielleicht schönere Fehlermeldungen mit static_assert bekommen, aber das ist auch mühselig.) Nimm Funktoren. 😉



  • Ich meinte, dass so sichergestellt ist, dass der Datentyp der Funktionen in der Funktion stimmt. Bei deiner Variant ist es das nämlich nicht.



  • Die erinnerung schrieb:

    Ich meinte, dass so sichergestellt ist, dass der Datentyp der Funktionen in der Funktion stimmt. Bei deiner Variant ist es das nämlich nicht.

    😕 Lesen -> Denken -> Verstehen. Natürlich meintest du das. Ändert aber nichts daran, dass du ohne SFINAE Tricks oder static_assert bei einem Template nie sicher sein kannst, dass man einen ordentlichen Typ vorgesetzt bekommt. Egal wo. Das ist ziemlich blöd, aber ohne Concepts nicht vermeidbar. Und ich halte es für ziemlich großen Quatsch, die wesentlich ⚠ schlechtere Lösung zu bevorzugen, nur um sich selbst mit einem falschen Eindruck von Typsicherheit zu beglücken.



  • Ok. Soweit klar, aber std::string wird der Compiler nicht akzeptieren, weil der Operator - vorkommt und vorallem die Funktion abs(). Die lässt nur numerische Typen zu und das ist doch genau das, was er braucht?

    Außerdem haben wir noch die Operatoren / und <. < unterstützen zwar viele Typen, aber / so gut wie ausschließlich numerische.

    Wobei ich sagen würde, in beide Fällen mekert der Compiler, wenn man Mist eingibt.



  • Die erinnerung schrieb:

    Wobei ich sagen würde, in beide Fällen mekert der Compiler, wenn man Mist eingibt.

    Ja, natürlich. Da muss man schon sehr viel Glück haben, dass man da für T etwas wählt, das funktioniert, aber irgendwie Quatsch ist. Das kann quasi nur Absicht sein. Aber das ist ja auch gar nicht das Problem. Denn was man eigentlich erreichen möchte, ist eine Fehlerbehandlung wie bei normalen Funktionen:

    double div(double a, double b)
    {
      return a / b;
    }
    
    int main()
    {
      div("Hallo", "Welt"); // Fehler beim Aufrufer
    }
    

    Und was man nicht möchte, ist

    template <typename T>
    T div(T a, T b)
    {
      return a / b; // Fehler taucht erst hier auf, weil kein passender operator / 
    }
    
    int main()
    {
      div("Hallo", "Welt");
    }
    

    Und letzteres kann halt extrem beknackte Fehlermeldungen geben, wenn man sich dann erstmal durch 5 Template-Stacks kämpfen muss. Obwohl der eigentlich Fehler nur sein sollte: Hey, dein Typ erfüllt die Anforderungen nicht! Deswegen sind Concepts ja so wichtig für die Sprache, obwohl sie primär nur ein "usability Feature" sind.



  • Jo, das ist ein Problem, aber es lässt sich halt nicht umgehen.

    Wenn man sowas in einer Libary einbaut, sollte man in der Dokumentation daruf hinweisen.


Anmelden zum Antworten