Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It is indeed interesting that people ask this over and over again. One reason may be that the proposed solutions are not easy to understand. I for one had problems understanding and implementing them. (the solutions did not work out of the box for me, as you might expect.)</p> <p>With the help of <a href="https://stackoverflow.com/users/423791/tlamadon">tlamadon</a> I just figured out a solution that may be helpful here as well. Let's see what you guys think. </p> <p>So just to recap, the problem is that you have a class that contains a member function on which you want to operate with something from the GSL library. Our example is useful if the GSL interface requires a </p> <pre><code>gsl_function F; </code></pre> <p><a href="http://www.gnu.org/software/gsl/manual/html_node/Providing-the-function-to-solve.html#Providing-the-function-to-solve" rel="nofollow noreferrer">see here for a definition.</a></p> <p>So here is the example class:</p> <pre><code>class MyClass { private: gsl_f_pars *p; // not necessary to have as member public: double obj(double x, void * pars); // objective fun double GetSolution( void ); void setPars( gsl_f_pars * xp ) { p = xp; }; double getC( void ) ; // helper fun }; </code></pre> <p>The objective of this exercise is to be able to </p> <ol> <li>initiate <code>MyClass test</code>, </li> <li>supply it with a paramter struct (or write a corresponding constructor), and</li> <li>call <code>test.GetSolution()</code> on it, which should return whatever the GSL function was used for (the minimum of <code>obj</code>, a root, the integral or whatever)</li> </ol> <p>The trick is now to put have an element in the parameter <code>struct gsl_f_pars</code> which <em>is a pointer to MyClass</em>. Here's the struct:</p> <pre><code>struct gsl_f_pars { double a; double b; double c; MyClass * pt_MyClass; }; </code></pre> <p>The final piece is to provide a wrapper that will be called inside <code>MyClass::GetSolution()</code> (the wrapper is a stand in for the member function <code>MyClass::obj</code>, which we cannot just point to with <code>&amp;obj</code> inside the class). This wrapper will take the parameter struct, dereference <code>pt_MyClass</code> and evaluate <code>pt_MyClass</code>'s member <code>obj</code>: </p> <pre><code>// Wrapper that points to member function // Trick: MyClass is an element of the gsl_f_pars struct // so we can tease the value of the objective function out // of there. double gslClassWrapper(double x, void * pp) { gsl_f_pars *p = (gsl_f_pars *)pp; return p-&gt;pt_MyClass-&gt;obj(x,p); } </code></pre> <p>The full example is a bit too long to post here, so I put up a gist. It's a <a href="https://gist.github.com/floswald/7103615" rel="nofollow noreferrer">header file</a> and a <a href="https://gist.github.com/floswald/7103639" rel="nofollow noreferrer">cpp file</a>, it should be working wherever you have GSL. Compile and run with </p> <pre><code>g++ MyClass.cpp -lgsl -o test ./test </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. COLike your effort to come with a simpler explanation. In my opinion this is a LOT of extra code that can be implemented in 2 lines using std::bind and the wrapper that you just write once in your life. I truly believe (because I've already implemented this when I was learning c++) that wrapping every single member function with a global function is not only cumbersome but also polute your code with a lot of extra functions (if your code is very big and you need to do this a lot of times)
      singulars
    2. COHi @ViniciusMiranda, in this particular example, this is not a lot extra code; in fact, writing your wrapper is more code than writing mine. That said, I'm sure you are right that your way is the "proper" one when it comes to have to do this trick many times in a project. It didn't work for me because I don't use C++11, which your solution makes ample use of. I'm a bit wary of using C++11 functionality because I have to run my stuff on several HPC systems and it's likely i'll find trouble there. I should try out though. thanks for your comment!
      singulars
    3. COYou may be unable to use C+11 today, but you wont come back after you see how powerful it is (the HPC cluster where I run my programs updates compiler fast ). Example of another situation where how c++11 help you - when I need to allocate a gsl struct (ex: integration workspace), I immediately transfer the pointer to a std::unique_ptr with custom deleter (to teach unique_ptr how to delete the struct). Then, my code is exception safe and I also don't need to delete myself the gsl pointers (you define the custom deleter once in a .hpp). It is almost as good as having garbage collector.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload