Designfrage: Werte erst berechnen wenn notwendig



  • Angenommen ich habe folgende Klasse:

    template<class T>
    		class Statistics {
    		public:
    			// Kann die Reihenfolge u.U. ändern (z.B. bei median)
    			Statistics(std::vector<T>& vecData) : m_refVecData(vecData) {
    
              }
    
    private:
           std::vector<T>& m_refVecData;
    };
    

    Jetzt bietet die Klasse verschiedene Funktionen an:

    inline double sum() const {
    				return std::accumulate(m_refVecData.begin(), m_refVecData.end(), 0.0);
    			}
    

    Die Summe soll also erst berechnet werden, wenn sie auch wirklich gebraucht wird. Hier schon das erste Problem. Wenn jemand die Funktion zweimal aufruft, dann wird sie auch zweimal berechnet. Soll ich die Summe jetzt als member-variable speichern und dazu einen boolean, ob sie bereits berechnet wurde?

    Das gleiche dann bei anderen Funktionen, die stellenweise auch voneinander abhängen:

    inline double mean() const {
    				return sum() / m_refVecData.size();
    			}
    

    Wie würdet ihr das lösen?



  • Vlt. gar keine Klasse und alles in einzelne Template-Funktionen? Das kam mir noch in den Sinn 😕



  • Designer32 schrieb:

    Soll ich die Summe jetzt als member-variable speichern und dazu einen boolean, ob sie bereits berechnet wurde?

    Das kann man durchausmachen, wenn Geschwindigkeit wichtiger als Speicherplatz ist. Aber nicht vergessen den boolean zu setzen, sobald sich Werte im Array aendern.



  • Jupp, eine freie Funktion ist hier sinnvoller:

    double sum(std::vector<double> const & vecData) {
        return std::accumulate(vecData.begin(), vecData.end(), 0.0);
    }
    

  • Mod

    Wenn schon denn schon 🤡

    template <typename Range>
    constexpr auto sum(Range const& range) {
        using std::begin; using std::end;
        return std::accumulate(begin(range), end(range), typename std::iterator_traits<decltype(begin(range))>::value_type{});
    }
    




  • Lazy initialization! In deinem Fall halt Lazy-Sum. 🙂


Anmelden zum Antworten