Komisches Template Problem



  • Ich weiss nicht wo ichs reinschreiben soll, entweder hier oder in compiler, also kein böses blut falls es falsch sein sollte, ok 😉

    Also, hier das Problem:
    ich hab in einer Datei ( data.h ) folgende Definitionen

    typedef struct tagBSSETTINGS{
    	unsigned beep_int;
    	bool beep_enable;
    	char drive_one[2];	   
    	char drive_two[2];
    }BSSETTINGS;
    
    template<class T> T GetFromFile(const char* FileName);
    template<class T> bool WriteToFile(const char* FileName, const T t);
    

    und in einer Datei (data.cpp) die Funktionsrümpfe.

    so, nun binde ich in einer anderen cpp datei die data.h ein und rufe beide funktionen auf

    #include "Data.h"
    //...
    WriteToFile("settings.bs",settings);
    settings = GetFromFile("settings.bs");
    //...
    

    so, nun das Problem: WriteFile beim compilieren, anstandslos.
    GetFromFile, ... folgender Fehler

    bruni error LNK2019: unresolved external symbol
     "bool __cdecl GetFromFile<struct tagBSSETTINGS>(char const *,struct tagBSSETTINGS)" 
    (??$GetFromFile@UtagBSSETTINGS@@@@YA_NPBDUtagBSSETTINGS@@@Z) referenced in function 
    "int __stdcall SettingsDlgProc(struct HWND__ *,unsigned int,unsigned int,long)" (?SettingsDlgProc@@YGHPAUHWND__@@IIJ@Z)
    

    (ich hab auch schon scherzhalber die funtkion umbenannt und den gleichen funktionskopf wie der writetofile gegeben aber immer der gleiche mist ...)

    so, nun die frage:
    liegt das irgendwie an meinem compiler (hab vc7.1), oder hab ich da irgendwas falsch geschrieben ( also das da was nich dem standard entspricht oder, ... )

    ich bin langsam am verzweifeln hier ..

    ich bedank mich schonmal im voraus

    ciao

    alex

    edit: damits mit dem Titel paßt, sollte ich vielleicht noch dazu sagen, daß wenn ich es als 'normale' Funktion schreibe,
    spr.

    BSSETTINGS GetFromFile(const char* lpFileName);
    

    kompiliert vc es ohne irgendwelche Fehler.



  • das liegt daran, dass der Compiler bei GetFromFile nicht den Templatetyp auflösen kann, da musst du ihn explizit angeben

    zB.

    template<typename T> T foo(void);
    int i=foo<int>();
    


  • @kingruedi
    hab ich mal probiert,
    also:

    // definition data.h
    template<typename T> T GetFromFile(const char* lpFileName);
    
    //aufruf andere cpp
    settings = GetFromFile<BSSETTINGS>("settings.bs");
    

    hat aber leider nichts gebracht 😕 .

    er behauptet immernoch das er die funktion nicht finden kann:

    bruni error LNK2019:
    unresolved external symbol "struct tagBSSETTINGS __cdecl GetFromFile<struct tagBSSETTINGS>(char const *)"
    (??$GetFromFile@UtagBSSETTINGS@@@@YA?AUtagBSSETTINGS@@PBD@Z) referenced in function
    "int __stdcall SettingsDlgProc(struct HWND__ *,unsigned int,unsigned int,long)" (?SettingsDlgProc@@YGHPAUHWND__@@IIJ@Z)
    

    mfg

    alex



  • Der Compiler findet die Implementierung der Funktion nicht!

    Template Funktionen müssen in der gleichen Übersetzungseinheit implementiert sein, wo sie aufgerufen werden (außer du benutzt export, was aber wohl nur der Comeau unterstützt)



  • Template Funktionen müssen in der gleichen Übersetzungseinheit implementiert sein, wo sie aufgerufen werden (außer du benutzt export, was aber wohl nur der Comeau unterstützt)

    hm, ok..
    kannst du das bitte nochmal ausführlicher schreiben ich versteh nur zuz ca. 20 % was du da gerade gesagt hast 😉

    zudem was ich verstehe:
    wieso funktioniert dann "WriteToFile" ?



  • k1ro schrieb:

    Template Funktionen müssen in der gleichen Übersetzungseinheit implementiert sein, wo sie aufgerufen werden (außer du benutzt export, was aber wohl nur der Comeau unterstützt)

    hm, ok..
    kannst du das bitte nochmal ausführlicher schreiben ich versteh nur zuz ca. 20 % was du da gerade gesagt hast 😉

    Die Funktionsrümpfe müssen auch in der *.h stehen.



  • @void* & kingruedi:

    cool, danke es funktioniert.
    ich verstehe zwar nich wieso, zudem empfinde ich es irgendwie als schlechten stil funktionsrümpfe in ne header zu schreiben, aber es funktioniert 😉

    danke !

    mfg

    k1ro



  • k1ro schrieb:

    ich verstehe zwar nich wieso, zudem empfinde ich es irgendwie als schlechten stil funktionsrümpfe in ne header zu schreiben, aber es funktioniert 😉

    templates werden zur compile zeit ausgwertet (ähnlich wie inline funktionen) und müssen deshalb von überall zugänglich sein (ähnlich wie inline funktionen)



  • templates werden zur compile zeit ausgwertet (ähnlich wie inline funktionen) und müssen deshalb von überall zugänglich sein (ähnlich wie inline funktionen)

    OK, danke für die Erklärung !



  • hallo,

    du kannst die Implementierung ruhig in der *.cpp belassen, musst nur da wo du es brauchst nicht nur die header-datei sondern auch die Implementierung inkludieren. das gibt sonst immer fehler mit "unaufgelösten externen Symbolen..".
    Warum es mit der einen Methode geht weiss ich auch nicht..
    inkludier einfach beide und du hast ruhe

    mfg



  • irfan schrieb:

    Warum es mit der einen Methode geht weiss ich auch nicht..

    dann lies mal meinen beitrag.

    die datei würde ich dann aber nicht .cpp nennen, sondern .inl .tmpl .def oder sonstwie - auf jedenfall aber anders als eine echte ÜE


Anmelden zum Antworten