how to avoid static member function when using gsl with c++

后端 未结 4 788
小鲜肉
小鲜肉 2020-11-28 14:21

I would like to use GSL within a c++ class without declaring member functions as static. The reason for this is because I don\'t know them too well and I\'m not

相关标签:
4条回答
  • 2020-11-28 15:07

    You can easily wrap member functions using the following code (which is a well known solution)

     class gsl_function_pp : public gsl_function
     {
        public:
        gsl_function_pp(std::function<double(double)> const& func) : _func(func){
          function=&gsl_function_pp::invoke;
          params=this;
        }    
        private:
        std::function<double(double)> _func;
        static double invoke(double x, void *params) {
         return static_cast<gsl_function_pp*>(params)->_func(x);
       }
    };
    

    Then you can use std::bind to wrap the member function in a std::function. Example:

    gsl_function_pp Fp( std::bind(&Class::member_function, &(*this),  std::placeholders::_1) );
    gsl_function *F = static_cast<gsl_function*>(&Fp);     
    

    However, you should be aware about the performance penalties of std::function before wrapping member functions inside gsl integration routine. See template vs std::function . To avoid this performance hit (which may or may not be critical for you), you should use templates as shown below

    template< typename F >
      class gsl_function_pp : public gsl_function {
      public:
      gsl_function_pp(const F& func) : _func(func) {
        function = &gsl_function_pp::invoke;
        params=this;
      }
      private:
      const F& _func;
      static double invoke(double x, void *params) {
        return static_cast<gsl_function_pp*>(params)->_func(x);
      }
    };
    

    In this case, to call a member function you need the following

     Class* ptr2 = this;
     auto ptr = [=](double x)->double{return ptr2->foo(x);};
     gsl_function_pp<decltype(ptr)> Fp(ptr);     
     gsl_function *F = static_cast<gsl_function*>(&Fp);   
    

    PS: the link template vs std::function explains that compiler usually has an easier time optimizing templates than std::function (which is critical for performance if your code is doing heavy numerical calculation). So even tough the workaround in the second example seems more cumbersome, I would prefer templates than std::function.

    0 讨论(0)
  • 2020-11-28 15:14

    Sorry, but what you're trying to do doesn't make any sense. Whatever thread safety issues you're worried about, they won't be solved by adding or removing the static keyword.

    The only reason why you would make g non-static would be if an instance of A was somehow required for g's operation. And g's current implementation doesn't require such an instance.

    Note you can also make g a global function, without the static keyword. There would be no visible difference in your case. However it's better style in your case to have g in the class which makes use of it, as a static function.

    Also, Here is some related material about pointers to (static/non-static) member functions.

    0 讨论(0)
  • 2020-11-28 15:24

    Why are you worried about the static function in this case? Variables and/or objects declared in a static function are not shared between different threads unless they are static themselves (which in your case they are not).

    Is your code failing to do something?

    0 讨论(0)
  • 2020-11-28 15:26

    GSL takes a C-type functions “int (*)(char,float)” rather than C++-type “int (Fred::*)(char,float)”. To convert a member function to the C-type function, you need to add static.

    see Is the type of “pointer-to-member-function” different from “pointer-to-function”?

    0 讨论(0)
提交回复
热议问题