C++ Funktions-Templates - andere Konstante in Implementierung möglich?



  • Hallo,

    kann ich für folgendes "Problem" C++ Templates verwenden?

    Ich habe eine Funktion Ai und eine Funktion As, die beide sehr ähnlich sind. Sie unterscheiden sich nur in Datentypen und einer Konstante voneinander. Der Code von As ist also quasi ein Copy&Paste von Ai mit leichten Modifikationen.

    Beispiel (fiktiv):

    unsigned int Ai(unsigned int x, unsigned int y)
    {
      if(x < 100)
        return x;
      else
        return y;
    }
    
    unsigned short As(unsigned short x, unsigned short y)
    {
      if(x < 50)
        return x;
      else
        return y;
    }
    

    Kann man das mit Templates lösen? Wie bekomme ich die Konstante 100 bzw. 50 in abhägigkeit des Datentyps?



  • Das ist z.B. über Hilfsstrukturen möglich (wenn die Konstante wirklich nur vom Datentyp abhängt):

    template<class T>
    struct constholder  // oder irgendein anderer name
    {
    };
    
    // Spezialisierung für unsigned int
    template<>
    struct constholder<unsigned int>
    {
        static const unsigned int value = 100;
    };
    
    // Spezialisierung für unsigned short
    template<>
    struct constholder<unsigned short>
    {
        static const unsigned short value = 50;
    };
    
    // weitere Spezialisierungen
    
    template<class T>
    T A(T x, T y)
    {
      if(x < constholder<T>::value)
        return x;
      else
        return y;
    }
    

    Das hat noch den hübschen Nebeneffekt, dass die Funktion nur mit Typen benutzt werden kann, für die eine Spezialisierung von constholder<T> existiert (weil es value in der allgemeinen Struktur nicht gibt).



  • Vielleicht so?

    template <typename Ty_, std::size_t constant>
    Ty_ AT(Ty_ x, Ty_ y) {
       if(x < constant)
          return x;
       else
          return y;
    }
    


  • hi

    template<int x, class T>
    T Ax(T val1, T val2)
    {
       return (val1 < x) ? val1 : va2;
    }
    
    Ax<50,unsigned short>(30,10);
    

    ungetestet

    Meep Meep



  • Das könntest du mit Spezialisierung und einer Hilfsfunktion lösen.

    (nicht getestet)

    template<class T, int count>
    T A_ ( T x, T y)
    {
      if(x < count)
        return x;
      else
        return y;
    }
    
    template<class T>
    T A (T x, T y) {}
    
    template<>
    unsigned int A<unsigned int> (unsigned int x, unsigned int y) { A_<unsigned int,100> (x, y);}
    
    template<>
    unsigned short A<unsigned shor> (unsigned short x, unsigned short y) { A_<unsigned short>, 50> (x, y);}
    

    Wenn du natürlich den Wert angeben kannst/willst dann gehts auch einfacher. Oder man übergibt den Wert auch gleich dynamisch.



  • Danke für eure Vorschläge.

    Wichtig ist, dass diese Kosntante nur innerhalb der Implementierung bleibt.

    Sprich ein Benutzer ruft Ai oder As auf und weiss garnichts davon dass darin eine 100 oder 50 gebraucht wird. Das soll also beim Aufruf also auch nicht "übergeben" werden müssen.

    Der Vorschlag von ipsec ist dann warscheinlich das zutreffendste.
    In der Tat soll es nur die Implementirungen geben für dessen Datentypen auch eine Konstante angegeben wird.



  • stefan-tiger schrieb:

    Kann man das mit Templates lösen? Wie bekomme ich die Konstante 100 bzw. 50 in abhägigkeit des Datentyps?

    hattest ja auch noch geschrieben gehabt.
    tjo wer lesen kann is klar im vorteil 🙄

    wuerde also mit meinem beispiel so aussehen:

    template<class T> struct constant { };
    template<> struct constant<unsigned short> { static const unsigned short val = 50; };
    template<> struct constant<unsigned int> { static const unsigned short val = 100; };
    
    template<class T>
    T Ax(T val1, T val2)
    {
       return (val1 < constant<T>::val) ? val1 : val2;
    }
    

    Meep Meep



  • Ich glaube mit Templates geht das doch nicht so wie gewünscht.

    So weit ich weiss muss ich dann die ganze Implementierung im Quellecode mitgeben und diese wird dann inkludiert. Es werden keine dedizierten Objekt-Dateien erzeugt.

    Templates scheinen mir auch etwas zu unflexibel.
    Beispielsweise will ich für alle integer Datentypen für unsigned und signed sowie für float/double eine andere Implementierung. Auch bestimmte Kombinationen haben bestimmte Implementierungen.

    Ich denke wenn ich mir selbst einen Code-Generator schreibe, der dann cpp Dateien mit ausformulierten Implementierungen ohne Templates erzeugt, ist das für mich besser.


Anmelden zum Antworten