pow in metatemplates: ?:-Vergleich schlägt fehl



  • Hallo,
    ich versuche pow in MetaTemplates zu programmieren, aber irgend wie scheint der Vergleichs Operator ?: fehl zu schlagen, sowohl beim GCC, ICC, als auch beim Comeau.

    #include <iostream>
    
    template<long B,unsigned long E>
    struct pow_helper {
      static const double value;
    };
    template<long B,unsigned long E>
    const double pow_helper<B,E>::value=B*pow_helper<B,E-1>::value;
    
    template<long B>
    struct pow_helper<B,0> {
      static const double value;
    };
    template<long B>
    const double pow_helper<B,0>::value=1;
    
    template<long B,long E>
    struct pow {
      static const double value;
    };
    template<long B,long E>
    const double pow<B,E>::value= E<0 ? 1.0/pow_helper<B,-E>::value :
      pow_helper<B,E>::value;
    //hier schlägt das E<0 fehl und es wird immer der "else" Part aufgerufen;
    // Auch wenn man E<0 durch true oder false ersetzt
    
    int main() {
      std::cout << pow<10,-3>::value << std::endl;
    }
    

    Was ist falsch an dem Code? Und wie kann man es richtig machen?



  • Bei templates wertet der immer beide Konstanten aus. In diesem Fall ist der Workaround recht einfach:

    template<long B,long E>
    const double pow<B,E>::value= E < 0 ? 1.0/pow_helper<B, E < 0 ? -E : E>::value :
      pow_helper<B, E < 0 ? -E : E>::value;
    


  • danke, jetzt geht es



  • Ne etwas beiläufige Frage:

    template<long B,unsigned long E>
    struct pow_helper {
      static const double value; // <-- wofür hier double ?
    };
    

    Die beiden Templateparameter sind ja eh integrale Typen.
    Bei pow is es klar, wegen dem 1.0, aber bei long * long ?

    Führt imho nur zu Rundungsfehlern / Scheingenauigkeit.



  • achso, dass war nur ein C&P Fehler, weil ich den Code neu programmiert habe um hier den Fehler zu veranschaulichen.


Anmelden zum Antworten