Allgemeine Frage zu Templaet "policies"



  • Hallo,
    ich habe mal eine allgemeine Frage an euch: Nehmen wir an, es gibt eine Klasse, mit der Benutzer arbeiten sollen. Diese Klasse ändert ihr Verhalten aufgrund eines Templateparameters (sowas in Richtung policy Classes). Welchen "Stil" würdet ihr in folgendem Beispiel bevorzugen? (Es geht hier ums Prinzip, nicht darum, dass man es mit std::accumulate direkt implementieren könnte...)

    const int Add = 0;
    const int Mult = 1;
    
    template<int Policy> //0 = addiere, 1 = multipliziere
    class MathContainer
    {
        double value;
    public:
        void calculate(const std::vector<double>&);
    };
    
    //Möglichkeit 1: Spezialisierung
    template<int Policy> //"default" Fall
    void MathContainer<Policy>::calculate(const std::vector<double>& vec)
    {
        value = 0.;
        for(std::vector<double>::size_type i=0; i!= vec.size(); ++i)
            value += vec[i]; 
    }
    template<> //weitere Spezialisierungen
    void MathContainer<1>::calculate(const std::vector<double>& vec)
    {
        value = 1.;
        for(std::vector<double>::size_type i=0; i!= vec.size(); ++i)
            value *= vec[i]; 
    }
    
    //Möglichkeit 2: if/else
    template<int Policy>
    void MathContainer<Policy>::calculate(const std::vector<double>& vec)
    {
        if(Policy==Mult)
            value = 1.;
        else
            value = 0.;
        for(std::vector<double>::size_type i=0; i!= vec.size(); ++i)
            if(Policy==Mult)
                value *= vec[i];
            else
                value += vec[i];
    }
    

    In dem Fall sollten Performance Fragen ja eigentlich egal sein, da der Compiler in beiden Fällen den gleichen Code produzieren sollte. Ich persönlich finde Möglichkeit 1 besser verständlich, da man sofort sieht, was gemeint ist. Außerdem ist die Spezialisierung im allgemeinen flexibler. Wie seht ihr das? Welche Version würdet ihr in einem so einfachen Fall wählen?



  • Ich sehe beides nicht als Policy.

    struct Addieren {
      template <typename T> defaultval() { return 0; }
      template <typename T> static void opeq(T& l, T const& r)
      { l += r; }
    };
    struct Multiplizieren {
      template <typename T> defaultval() { return 1; }
      template <typename T> static void opeq(T& l, T const& r)
      { l *= r; }
    };
    
    template<typename Policy> // Addieren oder Multipliziere
    class MathContainer
    {
        double value;
    public:
      calculate(const std::vector<double>& vec)
      {
        value = Policy::defaultval<double>();
        for(std::vector<double>::size_type i=0; i!= vec.size(); ++i)
            Policy::opeq(value, vec[i]);
      }
    };
    

    Das macht den Code nicht nur generischer (der Nutzer kann neue Policies hinzufügen), sondern auch übersichtlicher.


Anmelden zum Antworten