Template mit Funktionszeiger ohne Parameter-Typ



  • Hallo zusammen,

    Ich steh gerade auf dem Schlauch oder ich hab schon lange kein C++ mehr geproggt 🙄
    Ich habe folgendes (stark reduziertes) Konstrukt:

    class MyParamA{
    };
    
    class MyObjectA{
    public:
            const MyParamA& getParameter() const{
                    return this->param;
            }
    
    private:
            MyParamA param;
    };
    
    double fA(const MyParamA&){
            return 0;
    }
    
    template<double (*TParam)(const MyParamA&)>
    class MyTemplate{
    public:
    
    template<typename T>
    void doSomething(const T& t){
            TParam(t.getParameter());
    }
    
    };
    
    int main(int argc, char**)
    {
            MyTemplate<&fA> mt;
            MyObjectA moa;
            mt.doSomething(moa);
    }
    

    Das funktioniert ja auch wie ich es möchte.
    Jetzt hab ich analog dazu:

    class MyParamB{
    };
    
    class MyObjectB{
    public:
            const MyParamB& getParameter() const;
    };
    
    double fB(const MyParamB&);
    

    Wie kann ich diese Definition ändern

    template<double (*TParam)(const MyParamA&)>
    class MyTemplate{
            // ...
    };
    

    ohne einen zusätzlichen Template-Parameter für die Klasse zu ergänzen.
    Also theoretisch sollte es doch möglich sein, oder?
    Der Compiler hat doch alle Informationen.

    Gruß,
    XSpille



  • Ne, geht nicht.
    Es gibt keinen Template-Parameter Typ der zugleich ein Funktions-Typ UND ein Funktions-Zeiger wäre.



  • Ich danke dir vielmals hustbaer!!!

    Ich überlege, ob ich es nun etwa so machen soll:

    template<typename TFunction>
    class MyTemplate{
    public:
    
    template<typename T>
    void doSomething(const T& t){
            typedef typename TFunction::function_type function_type;
            TFunction::function(t.getParameter());
    }
    
    };
    
    template <typename TReturnType, typename TParamType, TReturnType (*TFunc)(TParamType)>
    struct FuncWrapper{
            typedef TReturnType (*function_type)(TParamType);
            static function_type function;
    };
    
    template <typename TReturnType, typename TParamType, TReturnType (*TFunc)(TParamType)>
    TReturnType (*FuncWrapper<TReturnType, TParamType, TFunc>::function)(TParamType) = TFunc;
    
    int main(int argc, char**) 
    {
            typedef FuncWrapper<double, const MyParamA&, &fA> my_func;
            MyTemplate<my_func> mt;
            MyObjectA moa;
            mt.doSomething(moa);
    }
    

    Gibt es sowas evtl. schon in boost o. ä. integriert?
    Kann man die Infos evtl. auch aus boost::function wieder ermitteln?
    Ich hab im leider bisher nichts gefunden.

    EDIT: Okay... Es ist spät... Aus der Template-Definition von boost::function wird man es
    natürlich nicht erhalten, da die Funktion ja Bestandteil eines spezifischen Objektes ist 🤡

    EDIT2:

    Alternativ ginge auch Folgendes:

    template<typename T>
    void doSomething(const T& t){
            TFunction::func(t.getParameter());
    }
    
    };
    
    template <typename TReturnType, typename TParamType, TReturnType (*TFunc)(TParamType)>
    struct FuncWrapper{
            static TReturnType func(TParamType param);
    };
    
    template <typename TReturnType, typename TParamType, TReturnType (*TFunc)(TParamType)>
    TReturnType FuncWrapper<TReturnType, TParamType, TFunc>::func(TParamType param){
            TFunc(param);
    }
    

    Welche der beiden Möglichkeiten würdet ihr weswegen bevorzugen?

    Kann man eigentlich auch etwas statisches wie

    static TReturnType operator()(TParamType param);
    

    (so klappts leider nicht) oder ähnlich implementieren, damit man

    TFunction(t.getParameter());
    

    aufrufen kann 🙂

    Gruß,
    XSpille


Anmelden zum Antworten