Funktor für aufsummieren



  • Gegeben eine Klasse T mit einer Funktion double sum() und einen vector<T>, wie kann ich in einer Zeile (mit Funktoren) die Bedingung "Sind für alle V aus dem vector<T> die sum() größer als N" formulieren?



  • double tmp;
    if (accumulate( meinVec.begin(), meinVec.end(), tmp, sum() ) > N) ...
    

    /edit pumuckl: aus [c++] [cpp]-Tags gemacht 😉


  • Mod

    Wofür brauchst du da einen Funktor?

    if (std::accumulate(dein_vector.begin(),dein_vector.end(), zaehler, sum) > N)
    


  • Wenn sum() memberfunktion von T ist, geht es dann so?

    double tmp;
    	while (accumulate(Eckpunkte.begin(), Eckpunkte.end(), tmp, &point::sum) > N)
    

  • Mod

    dsfgdfg schrieb:

    Wenn sum() memberfunktion von T ist, geht es dann so?

    double tmp;
    	while (accumulate(Eckpunkte.begin(), Eckpunkte.end(), tmp, &point::sum) > N)
    

    Nein, Pointer auf (nichtstatische) Memberfunktionen funktionieren anders. Erlaube mir jedoch die Gegenfrage: Wie sieht die genaue Deklaration von sum() aus? Fellhuhn und ich sind nämlich davon ausgegangen, dass es sich um eine Funktion handelt, die zwei Argumente annimmt und die Summe zurückggibt. Wenn dies nicht der Fall ist, musst du sum() irgendwie so hinbiegen, dass es zwei Argumente nimmt und die Summe zurückgibt, beispielsweise indem du eine weitere Funktion schreibst, die sum auf die richtige Weise aufruft.

    edit: Oder du schreibst gleich dein eigenes Äquivalent zu accumulate, dass sum() richtig benutzt. Damit entfernst du sich aber immer weiter von deinem Plan, Funktoren zu benutzen. Du könntest jedoch auch einen Funktor schreiben, der eine Sume berechnet und dann std::for_each mit diesem Funktor aufrufen. Ist es das, was du ursprünglich machen wolltest?



  • Ich verstehe deinen Satz nicht ganz: Soll fuer jedes Element in vector<T> geprueft werden, ob T.sum() > N ist? Das laesst sich wohl eher mit einer for-Schleife realisieren, da beim ersten Fehlschlag abgebrochen werden kann und nicht alle Elemente ueberprueft werden muessen.



  • Ich glaube er meint die Summe aller point::sum() Returnwerte. Also so:

    struct AddiereSum
    {
        double operator()( double sum, const point& next_point ) const
        {
            return sum + next_point.sum();
        }
    };
    
    int main()
    {
        using namespace std;
        vector< point > Eckpunkte;
        const double N = 13.0;
        if( accumulate( Eckpunkte.begin(), Eckpunkte.end(), double(0), AddiereSum() ) > N )
        {
            // die Summe aller point::sum()s in 'Eckpunkte' ist größer als N
        }
    

    ..oder?



  • Ich interpretiere es so, dass es quasi folgendes sein soll:

    if (vec[0].sum() > N && vec[1].sum() > N && .... )
    

    Das wäre dann in "kurz":

    template <class Comparator>
    struct CompareSumTo_t
    {
      CompareSumTo_t(Comparator const& c = Comparator()) : comp(c) {}
      bool operator()(T const& arg) { return comp(arg.sum()); }
    private:
      Comparator comp;
    };
    
    template <class T>
    CompareSumTo_t<T> compareSumTo(T const& t)
    {
      return CompareSumTo_t<T>(t);
    }
    
    if (vec.end() == std::find_if(vec.begin(), vec.end(), compareSumTo(std::bind2nd(std::less<int>(),N)) )
    

    Da lässt sich sicherlich auch was hässlicheres mit boost::bind / boost::lambda bauen...



  • pumuckl schrieb:

    Ich interpretiere es so, dass es quasi folgendes sein soll:

    if (vec[0].sum() > N && vec[1].sum() > N && .... )
    

    So verstehe ich die Frage auch.

    pumuckl schrieb:

    Da lässt sich sicherlich auch was hässlicheres mit boost::bind / boost::lambda bauen...

    Och, so hässlich ist das gar nicht:

    bool antwort = vec.end() == find_if( vec.begin(), vec.end(), 
      bind(less_equal<double>(),bind(&T::sum,_1),N) );
    

    (ungetestet)


Anmelden zum Antworten