Possible casting issue in declaration of function in header file

AI Thread Summary
The discussion centers on a compilation error arising from the use of a non-static member function as a parameter in a function call. The error indicates that a parameter of type 'double (*)(double, void *)' cannot accept a member function pointer like 'double (class1::*)(double, void *)'. The solution involves changing the function call in `func2` to pass `class1::func1` without the address-of operator '&', as member functions should be accessed through an instance of the class. Additionally, it is suggested to pass the instance of the class as part of the parameters to the function being called. This approach ensures that the member function can be correctly accessed within the context of its class.
CAF123
Gold Member
Messages
2,918
Reaction score
87
Hello all, see below for a snippet of a header file, class1.h, and source code file, class1.cpp, adjusted to reproduce the issue I am having. I have declared a series of functions in the .h file and their corresponding definitions in the .cpp file but when I compile I get the error:

class1.cpp:48:57: error: cannot initialize a parameter of type 'double (*)(double, void *)'
with an rvalue of type 'double (class1::*)(double, void *)'
convolute1(lowerBound,split,epsabs,epsrel,toystruct1,&class1::func1);

I think it is to do with how I declare the function convolute1 in the .h file involving the pointer and maybe there is some casting issue. I have tried a few things including making the func1 static but this gives me problems elsewhere in the code (not reproduced in the toy files below) so I was wondering if anyone could see an issue immediately? Thanks!

Header file, class1.h:
C++:
class class1 {
 
  struct toystruct_t {
    double a,b,c;
    };

  double func1(double z, void *p);
  double func2(toystruct_t toystruct);
 
  double convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *));
    
};

Source code file, class1.cpp:
C++:
#include <iostream>
#include <gsl/gsl_integration.h>
#include <math.h>
#include <complex>
#include "class1.h"

 struct toystruct_t
      {
        double a,b,c;
      };double class1::func1(double z, void *p)
{
   
    return 2.0;   //function here made trival as reproduces error I wish to discuss without adding further complication
}
              
double class1::convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *))
{
    double result;
    double err;
    double res;
   
    gsl_integration_workspace * coeffIntegralWorkspace = gsl_integration_workspace_alloc (1e8);
    gsl_function F;
    F.params = (void*)(&toystruct);
    F.function = func;
    gsl_integration_qags(&F, lowerBoundary, upperBoundary,
                         epsabs, epsrel, 1e8,
                         coeffIntegralWorkspace, &result, &err);
   
    gsl_integration_workspace_free(coeffIntegralWorkspace);
   
    res = result;
   
    return res;
}

double class1::func2(toystruct_t toystruct1)
{
  double lowerBound = -10.0;
  double upperBound = -4.0;
  double epsabs=1e-3;
  double epsrel=1e-3;

  double res  =
   convolute1(lowerBound,upperBound,epsabs,epsrel,toystruct1,&class1::func1);

  return res;
}

int main(int argc, const char * argv[]) {
    
     std::cout << "Hello World"  << std::endl;
  
 }
 
Last edited by a moderator:
Technology news on Phys.org
I might be wrong, but I think the problem comes where you call convolute1() in class1.cpp.
Change the last parameter in this call to get rid of &

C:
double res  =
   convolute1(lowerBound,upperBound,epsabs,epsrel,toystruct1,class1::func1);

The name of a function is an address -- the address of the entry point in the code for that function.
 
  • Like
Likes CAF123
You shouldn't pass a non-static class member function as a parameter, and there is no need to: code inside class1::convolute1() can access the current instance's func1() member as this->func1().

Mark44 said:
The name of a function is an address -- the address of the entry point in the code for that function.
But that address is not what you want for a non-static member function as the code there is not bound to an instance. Non-static member functions should (can?) only be accessed via the object to which they are bound.
 
  • Like
Likes CAF123
I took another look. You can't do this:
CAF123 said:
C++:
    F.params = (void*)(&toystruct);
    // func must be a pointer to an ordinary function, not a (non-static) class member function.
    F.function = func;
    gsl_integration_qags(&F, lowerBoundary, upperBoundary,
                         epsabs, epsrel, 1e8,
                         coeffIntegralWorkspace, &result, &err);

If you want a function that works with an instance of class1 (let's call it class1_obj although that's a terrible name) then you need to pass class1_obj as (part of) F.params which will be passed to your F.function as the params argument. F.function can then do params.class1_obj.func1().
 
  • Like
Likes CAF123
CAF123 said:
class1.cpp:48:57: error: cannot initialize a parameter of type 'double (*)(double, void *)'
with an rvalue of type 'double (class1::*)(double, void *)'
convolute1(lowerBound,split,epsabs,epsrel,toystruct1,&class1::func1);

Have you considered using functors, instead function pointers?
https://stackoverflow.com/a/6451911
 
  • Like
Likes CAF123
  • Like
Likes CAF123
CAF123 said:
Hello all, see below for a snippet of a header file, class1.h, and source code file, class1.cpp, adjusted to reproduce the issue I am having. I have declared a series of functions in the .h file and their corresponding definitions in the .cpp file but when I compile I get the error:

class1.cpp:48:57: error: cannot initialize a parameter of type 'double (*)(double, void *)'
with an rvalue of type 'double (class1::*)(double, void *)'
convolute1(lowerBound,split,epsabs,epsrel,toystruct1,&class1::func1);

I think it is to do with how I declare the function convolute1 in the .h file involving the pointer and maybe there is some casting issue. I have tried a few things including making the func1 static but this gives me problems elsewhere in the code (not reproduced in the toy files below) so I was wondering if anyone could see an issue immediately? Thanks!

Header file, class1.h:
C++:
class class1 {
 
  struct toystruct_t {
    double a,b,c;
    };

  double func1(double z, void *p);
  double func2(toystruct_t toystruct);
 
  double convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *));
 
};

Source code file, class1.cpp:
C++:
#include <iostream>
#include <gsl/gsl_integration.h>
#include <math.h>
#include <complex>
#include "class1.h"

 struct toystruct_t
      {
        double a,b,c;
      };double class1::func1(double z, void *p)
{
 
    return 2.0;   //function here made trival as reproduces error I wish to discuss without adding further complication
}
           
double class1::convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *))
{
    double result;
    double err;
    double res;
 
    gsl_integration_workspace * coeffIntegralWorkspace = gsl_integration_workspace_alloc (1e8);
    gsl_function F;
    F.params = (void*)(&toystruct);
    F.function = func;
    gsl_integration_qags(&F, lowerBoundary, upperBoundary,
                         epsabs, epsrel, 1e8,
                         coeffIntegralWorkspace, &result, &err);
 
    gsl_integration_workspace_free(coeffIntegralWorkspace);
 
    res = result;
 
    return res;
}

double class1::func2(toystruct_t toystruct1)
{
  double lowerBound = -10.0;
  double upperBound = -4.0;
  double epsabs=1e-3;
  double epsrel=1e-3;

  double res  =
   convolute1(lowerBound,upperBound,epsabs,epsrel,toystruct1,&class1::func1);

  return res;
}

int main(int argc, const char * argv[]) {
 
     std::cout << "Hello World"  << std::endl;
 
 }
I *think* (standards have changed rapidly), your last parameter should be declared as ``double (*func) (<etc>)``

Edit: it appears you are also trying to pass a member function as the last parameter. So the prototype is expecting something like a nonmember function, but in the implementation is an actual member function. I think that explains the error message.
 
Last edited:
  • Like
Likes CAF123

Similar threads

Back
Top