bind1st für Funktoren



  • Guten Abend,

    ich habe mir std::function selbst implementiert und bastle gerade an einem bind1st. Für Funktionen habe ich die Überladung schon hinbekommen, aber für Funktoren fällt mir da nichts sinnvolles ein. Auf variadic arguments kann ich ja kein typedef machen, ich habe den Tipp bekommen, mir folgende leere struct zu bauen und darauf zu typedefen:

    template <typename... Args> struct pack {};
    

    Irgendwie hilft mir das auch nicht weiter.

    Mein bind1st für Funktionen:

    template <typename ReturnType, typename BoundType, typename... ArgumentTypes>
            class binder1st
            {
                    function<ReturnType(BoundType, ArgumentTypes...)> functor;
                    typename std::remove_reference<BoundType>::type value;
    
            public:
                    binder1st(function<ReturnType(BoundType, ArgumentTypes...)> f, BoundType&& val) : functor(f), value(std::forward<BoundType>(val)) {}
    
                    ReturnType operator () (ArgumentTypes&&... args)
                    {
                            return functor(value, std::forward<ArgumentTypes>(args)...);
                    }
            };
    
            template <typename T, typename ReturnType, typename BinderType, typename... ArgumentTypes>
            binder1st<ReturnType, BinderType, ArgumentTypes...> bind1st(ReturnType (*f) (BinderType, ArgumentTypes...), T&& value)
            {
                    return binder1st<ReturnType, BinderType, ArgumentTypes...>(function<ReturnType(BinderType, ArgumentTypes...)>(f), std::forward<T>(value));
            }
    

    Kann mir jemand weiterhelfen?

    Grüße, PI



  • Habe nun auch noch eine Überladung für function:

    template <typename T, typename ReturnType, typename BinderType, typename... ArgumentTypes>
            binder1st<ReturnType, BinderType, ArgumentTypes...> bind1st(function<ReturnType(BinderType, ArgumentTypes...)> f, T&& value)
            {
                    return binder1st<ReturnType, BinderType, ArgumentTypes...>(f, std::forward<T>(value));
            }
    

    Ist es überhaupt machbar, beliebige Funktoren zu binden? Schließlich komm man ja nicht an die Typen des operator () ran, oder? Bei typedefs in den Funktoren kommt wieder das oben genannte Problem.



  • Du kennst aber std::bind? Vielleicht mal das anschauen.

    Btw: Die Boost-Menschen haben sowas schon vor fast einem Jahrzehnt hingekriegt. Ganz ohne Variadic Templates... 😉



  • Mach operator () zu einem Template, dann sind die Argument-Types völlig Hupe.



  • Natürlich kenn ich std::bind, ich will aber erst mal das implementieren. Das Ziel ist es, das ganze mit einer beliebigen Anzahl an Parametern zu verwenden können, das haben die sicherlich nicht so hinbekommen 😉



  • Buchbinder schrieb:

    Btw: Die Boost-Menschen haben sowas schon vor fast einem Jahrzehnt hingekriegt. Ganz ohne Variadic Templates... 😉

    Ja, aber auch nur weil sie genau das gemacht haben, zu dessen Vermeidung/Umgehung Variadic Templates gemacht wurden: tonnenweise Code wiederholen.

    Die Funktoren die boost::bind() und Konsorten zurückliefern überladen den operator () einfach zigfach - einen ohne Parameter, einen mit einem Parameter ... einen mit 20 Parametern.



  • 314159265358979 schrieb:

    Ist es überhaupt machbar, beliebige Funktoren zu binden?

    Ja, ist es, wie hab' ich ja schon geschrieben.

    Schließlich komm man ja nicht an die Typen des operator () ran, oder?

    Ne, kann nicht gehen, weil es mehr als einen operator () geben kann - der kann ja wie jede andere Funktion auch überladen werden.



  • hustbaer schrieb:

    Mach operator () zu einem Template, dann sind die Argument-Types völlig Hupe.

    Der Tipp ist schon mal super, warum ich da nicht draufgekommen bin. Allerdings bekomme ich hier eine Reihe Fehler, die ich nicht deuten kann. Der vollständigkeit halber ist alles dabei, um das Beispiel kompilierbar zu halten:
    http://ideone.com/BFkvs


Log in to reply