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.