Function pointers working as closures in C++

前端 未结 4 1414
情书的邮戳
情书的邮戳 2021-01-19 13:53

Is there a way in C++ to effectively create a closure which will be a function pointer? I am using the Gnu Scientific Library and I have to create a gsl_function. This funct

相关标签:
4条回答
  • 2021-01-19 14:22

    I'm guessing from all those "gsl_" prefixes that the library is not C++, but plain C. Which means it doesn't grok C++ closures (functors). You can't pass a C++ functor to a C function. You'll have to pass void pointers around, cross your fingers and reinterpret_cast them into C oblivion.

    0 讨论(0)
  • 2021-01-19 14:30

    Take a look at this simple example of combining boost::bind and boost::function.

    0 讨论(0)
  • 2021-01-19 14:31

    Though bradgonesurfing has given a nice answer that will work for converting closures into gsl_functions without any further thought, I would like to share with you the idiom for doing a direct translation from C++ into C.

    Supposing you have the closure:

    double a;
    [&a](double x){return a+x;}
    

    You would convert translate this into an equivalent function pointer idiom as follows:

    struct paramsAPlusX{
        double* a;
        paramsAPlusX(double & a_):a(&a_){}
    }
    double funcAPlusX(double x, void* params){
       paramsAPlusX* p= (paramsAPlusX*)params;
       return *(p->a) + x;
    }
    
    //calling code:
    double a;
    paramsAPlusX params(a);
    gsl_function f;
    f.function=funcAPlusX;
    f.params=&paramsAPlusX;
    //use f here.
    

    Many C libraries use this sort of idiom, and they don't all use a struct for it (they frequently pass it as two separate parameters to the function) so automatic conversion isn't always possible.

    0 讨论(0)
  • 2021-01-19 14:36

    I found below code at.

    http://bytes.com/topic/c/answers/657124-interface-problem

    // Use in combination with boost::bind.
    template<class F>
    static double gslFunctionAdapter( double x, void* p)
    {
        // Here I do recover the "right" pointer, safer to use static_cast
        // than reinterpret_cast.
            F* function = static_cast<F*>( p );
        return (*function)( x );
    }
    
    template<class F>
    gsl_function convertToGslFunction( const F& f )
    {
        gsl_function gslFunction;
    
        const void* p = &f;
        assert (p != 0);
    
        gslFunction.function = &gslFunctionAdapter<F>;
        // Just to eliminate the const.
        gslFunction.params = const_cast<void*>( p ); 
    
            return gslFunction;
    }
    

    and use this like

    gslFunction gslF = convertToGslFunction( boost::bind( &Sde::drift, &sde, _1 ) );
    
    0 讨论(0)
提交回复
热议问题