Get function pointer from std::function when using std::bind

前端 未结 3 1328
逝去的感伤
逝去的感伤 2020-11-29 06:29

I\'m trying to use std::function in conjunction with std::bind, but I\'m having some problems.

This works:

#include 

        
3条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-29 06:58

    This can be achieved using a little template meta-programming. I recently had use for this while writing a generic C++ wrapper around OpenGL GLUT (which depends on callback function pointers). The approach:

    1. Instantiate an instance of a singleton template type.
    2. Store your std::function as a member of to the singleton instance
    3. Invoke your std::function through a static member function (static member functions and free functions have the same type, so the "invoke" function can be used as a free function pointer)

    Tested under C++11 on GCC 4.8.

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    template 
    struct fun_ptr_helper
    {
    public:
        typedef std::function<_Res(_ArgTypes...)> function_type;
    
        static void bind(function_type&& f)
        { instance().fn_.swap(f); }
    
        static void bind(const function_type& f)
        { instance().fn_=f; }
    
        static _Res invoke(_ArgTypes... args)
        { return instance().fn_(args...); }
    
        typedef decltype(&fun_ptr_helper::invoke) pointer_type;
        static pointer_type ptr()
        { return &invoke; }
    
    private:
        static fun_ptr_helper& instance()
        {
            static fun_ptr_helper inst_;
            return inst_;
        }
    
        fun_ptr_helper() {}
    
        function_type fn_;
    };
    
    template 
    typename fun_ptr_helper<_UniqueId, _Res, _ArgTypes...>::pointer_type
    get_fn_ptr(const std::function<_Res(_ArgTypes...)>& f)
    {
        fun_ptr_helper<_UniqueId, _Res, _ArgTypes...>::bind(f);
        return fun_ptr_helper<_UniqueId, _Res, _ArgTypes...>::ptr();
    }
    
    template
    std::function::value, T>::type>
    make_function(T *t)
    {
        return {t};
    }
    
    int main()
    {
        std::cout << (void*)get_fn_ptr<0>(make_function(::sin))<

提交回复
热议问题