Templates / Funktionszeiger



  • Ich kämpfe mich gerade mühsam durch Templates und Funktionszeiger und bin dabei in einer Sackgasse gelandet.

    Die Funktion Serialize ist implementiert und getestet. Ebenfalls vorhanden und getestet ist die Klasse "Wein". Wie kann ich nun den Funktionszeiger "serialize" korrekt dem Template-Funktionszeiger "funptr" zuweisen?

    ************************************************
    main()
    ***********************************************

    template<class T> void(*funptr)(T& t, vector<unsigned short>& v);
    void serialize(Wein& w, vector<unsigned short>& v);

    int main()
    {
    funptr = serialize;

    return 0;
    }

    ************************************************
    ERORR:
    ***********************************************

    --------------------Konfiguration: Hashing - Win32 Debug--------------------
    Kompilierung läuft...
    main.cpp
    D:\Hashing\main.cpp('38') : error C2440: '=' : 'void (__cdecl *)(class Wein &,class std::vector<unsigned short,class std::allocator<unsigned short> > &)' kann nicht in 'void (__cdecl *)(
    &,class std::vector<unsigned short,class std::allocator<unsigned short> > &)' konvertiert werden
    Diese Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
    Fehler beim Ausführen von cl.exe.

    Hashing.exe - 1 Fehler, 0 Warnung(en)



  • Willst du den ersten Parametertyp des Funktionspointers variabel halten?
    Dann könntest sowas machen:

    #include <vector>
    
    struct Wein {};
    
    template <typename T>
    struct function_holder {
      typedef void (*p)(T&, std::vector<unsigned short>&);
    };
    
    void serialize(Wein& wein, std::vector<unsigned short>& v) {}
    
    int main() {
        function_holder<Wein>::p fp = &serialize;
        std::vector<unsigned short> v;
        Wein w;
    
        fp(w, v);
        return 0;
    }
    

    Edit: böse Smilies ..



  • Hallo Zeronull, danke für deine Antwort. Leider komme ich nur bedingt weiter, d.h. ich kann deinen Code nachvollziehen - denke ich zumindest - aber kann nicht wie erhofft das eigentliche Problem lösen...

    Die Funktionalitäten bleiben eigentlich erhalten, aber der variable Funktionszeiger befindet sich nun in der Parameterliste des Konstruktors der Template-Klasse "Hash"... 😕

    *huidawirdeinemanders*

    HASHKLASSE:

    #include "wein.h"
    #include <iostream>
    #include <vector>
    
    #ifndef HASH_H
    #define HASH_H
    
    using namespace std;
    
    template<class T> class Hash{
    public:
    	Hash(int tableSize, int Module, void(*fun_ptr)(T& t, vector<unsigned short>& v));
    private:
    	Hash(){}      // Std. Konstruktor wird kaschiert...
    };
    #endif //HASH_H
    

    MAIN:

    #include "hash.h"
    #include "wein.h"
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    void serialize(Wein& w, vector<unsigned short>& v) {}
    
    int main()
    {
    	Wein fusel;
    
    	// da bockt der Linker
    	Hash<Wein> myHashTable(1,1,serialize);
    
    	return 0;
    }
    

    FEHLERMELDUNG:

    --------------------Konfiguration: Hashing - Win32 Debug--------------------
    Kompilierung läuft...
    main.cpp
    Linker-Vorgang läuft...
    main.obj : error LNK2001: Nichtaufgeloestes externes Symbol "public: __thiscall Hash<class Wein>::Hash<class Wein>(int,int,void (__cdecl*)(class Wein &,class std::vector<unsigned short,class std::allocator<unsigned short> > &))" (??0?$Hash@VWein@@@@
    QAE@HHP6AXAAVWein@@AAV?$vector@GV?$allocator@G@std@@@std@@@Z@Z)
    Debug/Hashing.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise
    Fehler beim Ausführen von link.exe.
    
    Hashing.exe - 2 Fehler, 0 Warnung(en)
    


  • Na dann fehlt noch eine kleine Modifikation der Klasse Hash(+ eine korrekte Instanzierung in der main()), und die Sache hat sich:

    template <class T> 
    class Hash {
    public:
           typedef void (*func_ptr)(T& t, vector<unsigned short>& v);
           Hash(int tableSize, int Module, func_ptr fp) {}
    private:
            Hash() {}      // Std. Konstruktor wird kaschiert...
    };
    
    // ..
    
    int main()
    {
        Wein fusel;
        Hash<Wein> myHashTable(1, 1, &serialize);  // der Konstruktor bekommt die Adresse(!) von serialize
    
        return 0;
    }
    

    Alternativ kannst du die Funktionspointerdeklaration natürlich auch hardcoded im Konstruktor lassen.



  • ...*heul*...

    genau die habe ich versucht doch bleibe ich wieder an einem Linker-Fehler hängen. Ich habe alle meine #includes nochmals durchgesehen und denke, dass ich alle habe, was kanns denn noch sein?!?!

    Ich habe meine Files einmal als ZIP-File auf meine Seite gepostet, wäre sehr froh, wenn jemand Zeit hat es kurz anzuschauen...
    www.b-stoll.ch/cpp/hashing.zip

    Dank und Gruss



  • Ich denke der inhalt von hash.cpp muss noch in die hash.h.
    Kurt





  • ...unglaublich...

    da verbrat ich Schmalz ohne Ende und dann sowas 😮

    tausend Dank
    Bo


Anmelden zum Antworten