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;
    

Anmelden zum Antworten