Funktion als Template-Parameter uebergeben!



  • Hiho!

    Ich moechte einer Funktion eine andere Funktion als Template-Parameter uebergeben. Sieht in etwa so aus:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <string>
    using namespace std;
    
    template<typename callback> void parse_mapping(const char* dir)
    {
    	#define N 256
    	char cmd[N];
    	snprintf(cmd, N, "zcat %s/out.gz", dir);
    
    	char buffer[N];
    	FILE* input = popen(cmd, "r");
    
    	while (fgets(buffer, N, input) != NULL)
    	{
    		unsigned rid = atoi(buffer + 1);
    		char* i = strchr(buffer, '_');
    		unsigned occ = atoi(i + 1);
    		callback(rid, occ);
    	}
    	pclose(input);
    }
    
    void mapping_callback(unsigned rid, unsigned occ)
    {
    	cout << "i'm a dummy-function\n";
    }
    
    int main()
    {
    	string dir("test");
    	parse_mapping<mapping_callback>(dir.c_str());
    }
    

    Der GCC mag das aber nicht:

    g++ test.cpp
    test.cpp: In function ‘int main()’:
    test.cpp:41: error: no matching function for call to ‘parse_mapping(const char*)’
    

    Wie mach ich's richtig? Funktionspointer sind keine Option, da spaeter sowohl normale Funktionen als auch Functors mitgegeben werden sollen. boost::function ist ebenfalls keine Option, da die Funktion sehr, sehr, sehr Performance-kritisch ist (deswegen auch C-io).



  • Blue-Tiger schrieb:

    Wie mach ich's richtig? Funktionspointer sind keine Option, da spaeter sowohl normale Funktionen als auch Functors mitgegeben werden sollen.

    Du rufst deinen Funktionstypen als Funktion auf, das schmeckt dem Compiler natürlich nicht. Andererseits wiederum übergibst du eine Funktion an Stelle ihres Typen als Templateparameter, das passt auch nicht. Du musst schon noch eine Instanz des Typen haben, z.B. so:

    template<typename CB> void parse_mapping(const char* dir, CB& callback)
    //rest wie gehabt
    

    boost::function ist ebenfalls keine Option, da die Funktion sehr, sehr, sehr Performance-kritisch ist (deswegen auch C-io).

    Ahja. Und du hast schon nachgewiesen dass boost::function und C++-IO die Teile sind, die die Performance fressen? Kann ich irgendwie nicht ganz glauben.



  • Super, danke 🙂

    pumuckl schrieb:

    boost::function ist ebenfalls keine Option, da die Funktion sehr, sehr, sehr Performance-kritisch ist (deswegen auch C-io).

    Ahja. Und du hast schon nachgewiesen dass boost::function und C++-IO die Teile sind, die die Performance fressen? Kann ich irgendwie nicht ganz glauben.

    Ad C++ IO: ja, hab ich. Um fast Faktor 2 langsamer.

    Ad boost::function: nein, nicht probiert. Aber da das Callback ~10^11 mal aufgerufen wird koennt ich's mir schon vorstellen.



  • da spaeter sowohl normale Funktionen als auch Functors mitgegeben werden sollen.

    Du kannst dich auch einfach an der Implementation von std::sort halten. May the source be with you.



  • Blue-Tiger schrieb:

    Aber da das Callback ~10^11 mal aufgerufen wird koennt ich's mir schon vorstellen.

    Die Vorstellung spielt uns da manchmal ziemliche Streiche, vor allem wenns drum geht was der compiler so alles wegoptimieren kann. Da schmelzen so einige Zeilen Code einfach weg. => Wenn du nicht sehr genau Bescheid weißt was da wegoptimiert werden kann lieber messen.



  • Wieso nicht einfach:

    typedef void (*fPtr)(unsigned, unsigned);
    
    template<fPtr callback> void parse_mapping(const char* dir)
    {...}
    

    Edit: Ok, habs gesehen/gelesen 🙂



  • KasF schrieb:

    Wieso nicht einfach:

    typedef void (*fPtr)(unsigned, unsigned);
    
    template<fPtr callback> void parse_mapping(const char* dir)
    {...}
    

    Edit: Ok, habs gesehen/gelesen 🙂

    Weil er sich ncht auf Funktionspointer beschränken will.



  • KasF schrieb:

    Edit: Ok, habs gesehen/gelesen 🙂



  • knivil schrieb:

    da spaeter sowohl normale Funktionen als auch Functors mitgegeben werden sollen.

    Du kannst dich auch einfach an der Implementation von std::sort halten. May the source be with you.

    Das würde ich auch raten. Wenn er ja genau das Verhalten will, dann ist das ja genau die Lösung, die er sucht..

    Wundere mich, warum er das nicht schon von Anfang an so gemacht hat. 😉


Log in to reply