Template problem
-
Hi,
bei mir wird das nicht compiliert
template <typename T> inline T epsilon(void) { T x; if(x == typeid(float)) return 0.00001f; else if(x == typeid(double)) return 0.000000001; return 0; } int main() { std::cout << epsilon<float>();
ich bekomm bei == einen Fehler.
Wie kann ich das richtig machen? Und wie kann ichs machen das ich einfach nur
double x = epsilon<double>; ???
-
Erstens:
(typeid(x) == typeid(float))
Zweitens:
double x = epsilon();
-
so gehts aber auch:
template<class T,class U> class Equal{ static const bool Value=false; }; template<class T> class Equal<T,T>{ static const bool Value=true; }; template <typename T> inline T epsilon() { if(Equal<T,float>::Value) return 0.00001f; else if(Equal<T,double>::Value) return 0.000000001; return 0; }
vorteil: der compielr kann das viel einfacher optimieren, und so im zweifelsfall den if/else block direkt rausschmeissen
nächste alternative:
template <typename T> inline T epsilon() { return 0; } template <> inline float epsilon<float>() { return 0.00001f; } template <> inline double epsilon<double>() { return 0.000000001; }
ein bischen mehr schreibarbeit,dafür aber auch besser zu erweitern.
@monastero:
double x = epsilon();
wenn du mir erklären kannst, wie der compiler sich da den template parameter herleiten kann, kriegste nen Keks von mir
richtig wär
double x = epsilon<double>();
-
Das schreit doch geradezu nach ner Metafunktion:
template<typename t> struct epsilon { static const t val; }; template<> const float epsilon<float>::val = 0.0001f; template<> const float epsilon<double>::val = 0.0000001; // ... double x = epsilon<double>::val;
-
der compiler macht wahrscheinlich aus allen hier genannten versionen eh genau das gleiche
.
-
Hi,
ich hab den code grade ausprobiert! Funktioniert prima, außer das hier
template<typename t> struct epsilon { static const t val = 0; }; template<> const float epsilon<float>::val = 0.0001f; template<> const double epsilon<double>::val = 0.0000001;
error C2864: 'val' : only const static integral data members can be initialized inside a class or struct
-
liegt an den fließkommazahlen, die können keine compiletime konstanten sein, gibt auch keinen workaround..
-
otze schrieb:
@monastero:
double x = epsilon();
wenn du mir erklären kannst, wie der compiler sich da den template parameter herleiten kann, kriegste nen Keks von mir
struct epsilon { template <class T> operator T() const; }; template <> epsilon::operator float() const { return 0.0001f; } template <> epsilon::operator double() const { return 0.0000001; } int main() { double x = epsilon(); }
Bekomme ich für diese Schummelei jetzt einen Keks?
-
*** schrieb:
Hi,
ich hab den code grade ausprobiert! Funktioniert prima, außer das hier
template<typename t> struct epsilon { static const t val = 0; }; template<> const float epsilon<float>::val = 0.0001f; template<> const double epsilon<double>::val = 0.0000001;
error C2864: 'val' : only const static integral data members can be initialized inside a class or struct
Dann initialisiere einfach ausserhalb
template<typename t> struct epsilon { static const t val; }; template<typename t> const t epsilon<t>::val = 0;