Sas
Sas

Reputation: 563

Function pointers and C++ templates

I have a C++ code and i really need to use C function in it:

int procedure(... , S_fp fun , ...)

where fun - is a pointer to function which signature must be like that:

int fun(double* , double* , double)

The function, pointer to which i want to use, is a member of a class template:

template<int nPar> class PenaltyAlgorithm
{
public:
...
int Calculate(double* param, double* val, double prec)
{
   ...
}
...
}

As you can see, its signature is in order. But when I do this: procedure(... &PenaltyAlgorithm::Calculate, ...);

I get error:

error: cannot convert ‘int (PenaltyAlgorithm<30>::*)(double*, double*, double)’ to ‘int (*)(...)’ for argument ...

Please, help. If you need any additional info, please, write.

Thanks!!!

After reading answers, i understood that it's important to add information about class:

template<int nPar> class PenaltyAlgorithm
{
public:
int Calculate(double* param, double* val, double prec)
    {
    *val = comp_fun->Compute(param);
    }

double* RunAlgorithm()
    {
        ...
        procedure(... &PenaltyAlgorithm<nPar>::Calculate, ...);
        ... 
    }
...
private:
...
CompositeFunction<nPar>* comp_fun;
}

1). I can't use static fun, because this fun need to get access to members of class;

2). Can we use the fact, that we call 'procedure' from fun-member of class?

Upvotes: 3

Views: 1208

Answers (5)

Furkan Kıra&#231;
Furkan Kıra&#231;

Reputation: 51

If int procedure(... , S_fp fun , ...) must definitely be a C function, then there is no way to do what you are looking for directly. If you try to pass a class member function pointer it will have a hidden this pointer as its first argument in the stack, hence the prototypes won't match.

However you can create a global or static function which internally uses a saved instance pointer to access the PenaltyAlgorithm class indirectly. You can try the below:

1) Save the instance pointer of the class you want to pass to the procedure function to a global variable.

2) Create a new global function int CalculateGlobal(double* param, double* val, double prec)

3) Pass the CalculateGlobal function's pointer as the function pointer to your procedure function.

4) CalculateGlobal function can then use the saved instance pointer to access the specific class' internals.

Well this is not a good way of doing things of course...

Upvotes: 1

Jon Hanna
Jon Hanna

Reputation: 113392

Remember that int Calculate(double* param, double* val, double prec) as an instance member has a hidden this pointer, that a global function or static member won't have. Without this, it won't know which PenaltyAlgorithm to run it on.

Either the pointer should be of type int (PenaltyAlgorithm::*)(double* param, double* val, double prec) or Calculate should be static.

Upvotes: 1

Nick Veys
Nick Veys

Reputation: 23949

Calculate is a non-static method on PenaltyAlgorithm. It requires an instance of the PenaltyAlgorithm to execute, so it can't be fed to a C function as a plain function pointer.

Can the Calculate function be made static? If it can, it should work the same as a C function pointer, only it won't be able to access non-static data in the PenaltyAlgorithm class.

Upvotes: 3

Daniel
Daniel

Reputation: 31609

You have to make Calculate static, use

static int Calculate(double* param, double* val, double prec)

instead of

int Calculate(double* param, double* val, double prec)

Upvotes: 0

TJD
TJD

Reputation: 11906

You can't pass a pointer like that to a member function unless it is a static member function.

Upvotes: 0

Related Questions