operator+ als Parameter [solved]


  • Mod

    Der eingebaute Operator ist keine Funktion.

    Eine bessere Wahl wäre so etwas wie

    template <typename F>
    T fold(F func, T begin) const;
    

    Dann funktioniert auch std::multiplies<T>



  • double d = m.fold([] (double a, double b) { return a + b; }, 0.0);
    // oder
    double d = m.fold(std::plus<double>, 0.0);
    

    Edit: Ja, Funktionspointer ist natürlich Quatsch. Siehe camper.



  • Danke für die Tipps.

    Nur das hier:

    double d = m.fold(std::plus<double>, 0.0);
    

    funktioniert noch nicht:

    ..\src\LinearAlgebra.cpp:121:30: Fehler: expected primary-expression before »,« token
    

    Der Lambda-Ausdruck geht.

    Edit:
    Ich habs schon, es muss heißen:

    double d = m.fold(std::plus<double>(), 0.0);
    


  • Eine Frage hab ich noch:

    Vorher ging das hier:

    m.fold(std::min, 0.0)
    

    Jetzt nicht mehr, was ja auch logisch ist, da std::min nicht mehr eindeutig ist.
    Was wäre die eleganteste Lösung ohne C++11 (d.h. u.a. ohne Lambda-Ausdruck)?

    Ich hätte jetzt gedacht, dass

    m.fold(std::min<double>, 0.0)
    

    funktionieren müsste, das tut es aber nicht:

    Fehler: keine passende Funktion für Aufruf von »Matrix<double>::fold(<unresolved overloaded function type>, double)«
    

    Eine Lösung, die funktioniert, die ich aber nicht vollständig verstehe ich folgende:
    Matrix<T> hat das alte

    T fold(T (*func) (T, T), T begin) const;
    

    neben dem neuen

    template <class F>
    T fold(F func, T begin) const;
    

    Prinzipiell könnte aber das F der zweiten fold-Methode doch gleich T()(T,T) sein oder? Das heißt, dass eine Methode mit dem gleichen Namen und den gleichen Parametern zweimal vorkommt. Oder wird einfach zunächst überprüft, ob T()(T,T) passt und falls nicht die zweite fold-Methode benutzt?

    Wie würdet ihr das genannte Problem lösen?



  • Es wird zuerst die speziellere Überladung geprüft (also die mit T (T, T)) und wenn diese nicht passt, die andere Überladung verwendet. Der einzige Weg, den ich kenne, um die Überladung von std::min anzugeben, ist ein cast:

    static_cast<double(double, double)>(std::min)
    

  • Mod

    Ramanujan schrieb:

    Vorher ging das hier:

    m.fold(std::min, 0.0)
    

    Ist dein T eine Referenz auf const?



  • Anstatt zwei fold()-Methoden zu deklarieren müsste es ja auch über Template-Spezialisierung gehen. Irgendwie bekomm ich das aber nicht hin. Mein Versuch sieht bisher so aus:

    template <class T>
    template <class F>
    T Matrix<T>::fold(F func, T erg) const {
    	for (int i = 0; i < dim1_; i++)
    		for (int j = 0; j < dim2_; j++)
    			erg = func(erg, getEntry(i,j));
    	return erg;
    }
    
    template <class T>
    template <>  // hier Fehler: invalid explicit specialization before »>« token
                 //              einschließende Klassentemplates werden nicht explizit spezialisiert
    T Matrix<T>::fold(T(*func)(T,T), T erg) const { // Fehler: Template-ID »fold<>« für »T Matrix<T>::fold(T (*)(T, T), T) const« passt zu keiner Templatedeklaration
    	for (int i = 0; i < dim1_; i++)
    		for (int j = 0; j < dim2_; j++)
    			erg = func(erg, getEntry(i,j));
    	return erg;
    }
    

    @camper:
    T = double



  • Warum willst du die Funktion spezialisieren und nicht überladen?
    http://www.gotw.ca/publications/mill17.htm



  • wxSkip schrieb:

    Warum willst du die Funktion spezialisieren und nicht überladen?

    Unwissenheit xD

    Danke für den Link.


  • Mod

    <algorithm> deklariert 4 min-Überladungen

    template<class T> const T& min(const T& a, const T& b);
    template<class T, class Compare>
    const T& min(const T& a, const T& b, Compare comp);
    template<class T>
    T min(initializer_list<T> t);
    template<class T, class Compare>
    T min(initializer_list<T> t, Compare comp);
    

    Deshalb reicht es nicht, den Templateparameter explizit anzugeben. Anderseits ist mir auch nicht ganz klar, wie daraus ein double(double,double) entsehen soll..


Anmelden zum Antworten