CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jul 2008
    Posts
    17

    Problems with Member Function Addresses

    Hello,

    I am doing numerical work and am using the GSL (GNU scientific library) to help me with my endeavors. I recently had some code working procedurally, and then switched over to object oriented for the purposes of code reuse. The problem is I am having trouble using a library function that was working fine before.

    GSL defines a data type or class called gsl_function. It has has two members, one which is a pointer to a function and one which is a general void pointer (for the purposes of taking in parameters). The function pointer has prototype given by

    double (*function) (double x, void * params).

    So you define a function f that returns a double and takes in a double and a void pointer, and then you write

    gsl_function F;
    F.function = &f;

    I got this to work in a procedural setting. Now I am trying to do this in a class. My class has a member called myODE_dydx_ which has exactly the form I described for f. Then inside another member function called func, I have

    gsl_function F;
    F.function = &LensSolver::myODE_dydx_;

    (LensSolver is the name of my class) When I put this in, I get the error:

    error: cannot convert ‘double (LensSolver::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment.

    However, when I leave out the "LensSolver::" I still get this error in addition to another one, which I googled and found out is related to how member functions are addressed. I don't have the faintest clue what its telling me, much less how to solve it. Any help? (Also, in a stroke of inspiration I tried &this->myOde_dydx_ which didn't work at all)

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Problems with Member Function Addresses

    It's telling you that member functions take an implicit "this" parameter which subtly changes their signature.

    Are you currently using that void* parameter for anything? Usually in C libraries, a parameter like that is used for user context information. In that case, you could make myODE_dydx a free (possibly friend) function, or a static method, and specify "this" as the void* argument.

    This is a well-known difficulty of mixing C and C++, incidentally.

  3. #3
    Join Date
    Jul 2008
    Posts
    17

    Re: Problems with Member Function Addresses

    Thanks for the help Lindley. Someone on another forum had suggested using static to me, and then of course I had other problems. I had thought of passing this, the problem is that I am actually using the void* parameter to pass stuff. It's not the end of the world, what I can do is basically take the stuff I'm passing and make them data members of the class, and then I can access all that once I use this. Although I'm far from being an expert on C++ style, that seems stylistically wonky to me but it may be my best alternative. Thanks again for the response!

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Problems with Member Function Addresses

    Well, if you need access to both members of the object (call it class C, so "this" has type C*) and also some other data that you're passing in another struct (say, struct S), then you have two options:
    1) Make S a member of C, or make the members of S individual members of C.
    2) Add a C* pointer to S.

    Which of the two better suits your design is your call.

    Although I'm far from being an expert on C++ style
    This whole discussion is about C style, since you're restricted to the C way of doing things (function pointers, void*s, etc).

    The C++ approach to the problem would be to pass a functor, which could be easily generated directly from the member method using boost::bind() (or std::bind on the latest generation of compilers), and storing the functor in a boost::function (or again, a std::function if available). Then you wouldn't even need an additional struct S for multiple parameters; just give the member method the appropriate parameters and bind() in the relevant values.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Problems with Member Function Addresses

    Quote Originally Posted by Nirf View Post
    I don't have the faintest clue what its telling me,
    I'll put it to you this way -- a pointer to a non-static member function, and a pointer to a non-member function are two different animals. They are as different as a cat and an elephant, but you're trying to make one into the other. A non-static member function is purely a C++ invention. A C-based API knows nothing about these types.

    In addition, here is a question that will answer your question as to why you can't do what you wanted to do:

    How do you call a non-static member function using a pointer?

    If you see how it's done, then you would see immediately why your setup will not work. To call a non-static member function using a pointer, the syntax must include the object itself. It isn't as simple as what you see for 'C'-based function pointers, i.e.
    Code:
    (*fn)(param1, param2);
    The call has to look something like this:
    Code:
    (object.*fn)(param1, param2);
    Since GSL knows zilch about your objects, how will GSL create such a statement so that it can "callback" to your function? It can't -- the function call syntax just doesn't allow it to happen.

    Regards,

    Paul McKenzie

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problems with Member Function Addresses

    There are very useful examples here
    Victor Nijegorodov

  7. #7
    Join Date
    Jul 2008
    Posts
    17

    Re: Problems with Member Function Addresses

    Thanks everyone again, Lindley for the breakdown of 1) and 2) and and Paul for the great explanation of the differences between member functions and non-member functions, and VictorN for the link.

    Lindley, it makes me sad that I am forced to implement this stuff in C style and not use these cooler, newer, better ways of doing things (functors sound neat). The problem is that very high quality, complete numerical libraries such as GSL don't seem to be all that common, and in general the people writing them do not seem to put programming style as their top priority ( I can't blame them). If I could find one in C++ style, I would use it.

    More generally, I am starting to get a bit frustrated with C++ for having to deal with so many minutae like this to implement something which is relatively simple. I wish I could use an easier language like Python or Java; the problem is that for very fast numerical programming I don't feel that there is a legitimate contender to C and C++ (and their annoying mix). If you guys have good alternatives, either in terms of libraries or languages, I'd be happy to hear about them.

    Cheers.

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Problems with Member Function Addresses

    I'm not familiar with any other packages which do everything GSL does. However, there are a few which cover aspects of it. For instance, one linear algebra package I've been playing around with lately is Eigen.

    If you can lay out more specifically which features of GSL you're using I might be able to suggest a C++ equivalent to look at.

  9. #9
    Join Date
    Jul 2008
    Posts
    17

    Re: Problems with Member Function Addresses

    Recently I've used a lot of FFT and probabilistic (random number generation) stuff, at the moment I'm working primarily with ODE solvers. Although I would consider a non-GSL option for one particular aspect, there is a trade off here which compensates for the crappy style in some parts of GSL. That is that GSL is a consistent environment that I've worked with before. Before I started using GSL, every new project meant hunting for libraries, making them, installing them, getting them working, plowing through pages of documentation before I could do anything. Now, I know the gist of it, I know how to use half of the library, its a consistent framework, etc. C++ with GSL still isn't Matlab, but its much closer.

    When you're a physicist (like I am) it's always a tricky thing approaching coding. Usually your projects aren't done in huge teams (unless you're over in Geneva working on the supercollider) and what's more usually you aren't too concerned with code reuse (by other people) because let's face it, the benefit to you of the next graduate student (the one who takes over your project) having an easier time with your code is pretty small. So the benefits of really good style (i.e. all the cases in C++ where good style reasoning is based on making it easier for "the many" rather than "the few") are much less. In this case, it means having one consistent library is probably worth more to me, most of the time, than having to deal with multiple libraries that allow better style. That's why I mostly asked about complete libraries like GSL.

    Mind you, a lot of the time physicists go completely over to terrible style in a way that hurts themselves really badly. One of the pieces of legacy code I had to deal with, despite being written in C++ used pointers and arrays and news everywhere instead of vectors. Obviously the guy who wrote it wasted a lot of time (and left behind a lot of terrible memory leaks for me).

  10. #10
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Problems with Member Function Addresses

    Quote Originally Posted by Nirf View Post
    and what's more usually you aren't too concerned with code reuse (by other people)
    Good programming style always pays benefits. Code has a habit of lingering on way past its expected time of demise. Having a good readable style has benefits not only for the next poor soul who takes on your work, but also for you to understand & debug work you have done yourself. As for code reuse, I've found over the years that there are many opportunities for creating your own libraries to solve common problems. My first thought when creating a new algorithm is "Is this a specific case of a more general problem?". If the answer is 'yes' then I will probably add the generic solution to our library of parts.
    We had a guy here once who viewed a lot of code as 'throwaway'.
    I'm still trying to fix some of the mess even now.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured