Spezialisierung eines Funktionstemplates - redefinition



  • Hallo,

    ich frage mich warum mir der Compiler ein Redefinition error auswirft bei folgendem Code:

    template < typename T > inline T GeData2Value(const vdata& t_data) { return t_data.GetFloat(); }
    template < > inline LONG GeData2Value(const vdata& t_data) { return t_data.GetLong(); }
    

    Ist in einem Header und er sagt mir "Redefintion of T GeData2Value(const vdata&) with T=LONG". Hä? Kann mir einer mal erklären was ich da falsch mache. Irgendwie will ichs nich raffen. 😕

    Es bringt auch nichts, die Spezialisierung lediglich in der header zu deklarieren und die implementierung in einer .cpp zu setzen.

    Vielen Dank im voraus



  • template < typename T > inline T GeData2Value(const vdata& t_data) { return t_data.GetFloat(); }
    template < > inline LONG GeData2Value<LONG>(const vdata& t_data) { return t_data.GetLong(); }
    

    Und jetzt finde den kleinen, aber feinen Unterschied 😉

    Allerdings: was ist LONG? das riecht nach einem muffigen #define aus irgendeiner alten Bibliothek. Und wozu templates, wenn du eh nur zwei Varianten hast? (float und long) Den Typ musst du in dem Fall eh immer explizit angeben.



  • oh man, das isses?

    Der Datentyp kommt leider nicht von mir und du hast recht, ist schön dreckig über ein #define gelöst von der API die ich nutzen muss.

    Template weil von einem anderen Template aus aufgerufen.

    Anyway, vielen Dank!!!


  • Mod

    Katachi schrieb:

    Template weil von einem anderen Template aus aufgerufen.

    Das ist keine sinnvolle Begründung.



  • SeppJ schrieb:

    Katachi schrieb:

    Template weil von einem anderen Template aus aufgerufen.

    Das ist keine sinnvolle Begründung.

    Warum (toller kommentar im übrigen)? Wie würdest du es denn vereinfachen:

    template < typename T >
    T Class::do_it() const
    {
      //ca. 100 Zeilen code...
      return GeData2Value<T>(t_val);
    }
    

    Ohne GeData2Value als template wüsst ich mir nicht weiter zu helfen als diese funktion wiederum zu spezialisieren. Ich bin offen für tipps (natürlich könnte ich GeData2Value in der Klasse als template definieren und für die restlichen Überladen, aber wo liegt der Unterschied? Und wie könnte ich die GeData2Value Funktion dann von außerhalb aufrufen?)



  • Katachi schrieb:

    Der Datentyp kommt leider nicht von mir und du hast recht, ist schön dreckig über ein #define gelöst von der API die ich nutzen muss.

    Kannst du die dreckige API nicht wegkapseln, damit so ein Müll wie die #defines nicht dein ganzes Projekt verseuchen? 😉

    Template weil von einem anderen Template aus aufgerufen.

    Hab ich mir schon fast gedacht. In so einem Fall würde ich das Template allerdings für beide Typen spezialisieren und den nicht spezialisierten Fall undefiniert lassen. So kriegst du sofort eine aussagekräftige Fehlermeldung, wenn du Class<int> benutzt und musst dich nicht wundern, warum seltsame Werte rauskommen (du willst dann mit ziemlicher Wahrscheinlichkeit nicht (int)getFloat() als Ergebnis kriegen 😉



  • pumuckl schrieb:

    Kannst du die dreckige API nicht wegkapseln, damit so ein Müll wie die #defines nicht dein ganzes Projekt verseuchen? 😉

    Wäre wahrscheinlich nicht verkehrt...da müsste ich aber nochmal die anderen Mitprogrammierer fragen (leider bin ich nicht alleine in dem Projekt) und ich gebe zu da spielt dann sicherlich auch ein wenig die Faulheit mit rein 😉

    pumuckl schrieb:

    Hab ich mir schon fast gedacht. In so einem Fall würde ich das Template allerdings für beide Typen spezialisieren und den nicht spezialisierten Fall undefiniert lassen. So kriegst du sofort eine aussagekräftige Fehlermeldung, wenn du Class<int> benutzt und musst dich nicht wundern, warum seltsame Werte rauskommen (du willst dann mit ziemlicher Wahrscheinlichkeit nicht (int)getFloat() als Ergebnis kriegen 😉

    Mensch, das ist gar nicht mal so blöd. Thx, guter Tipp! Warum komm ich nich alleine auf sowas... 😃 Aber dafür hab ich ja mein c-plusplus forum 🙂 Notiert, gemerkt und abgeheftet


Anmelden zum Antworten