Numerical recipes: How to pass function as argument of function newt in c++
-
09-07-2021 - |
Question
My question is related to numerical recipes. I have a global function which computes the vector of functions to be minimized
VecDoub vecfunc(VecDoub_I x) {
// code is here
}
In a class function run, I tried to call the Numerical Recipes function newt, which reads my function vecfunc as shown,
class A {
void run() {
VecDoub_IO pt;
pt.resize(2);
pt[0] = 0.5;
pt[1] = 0.5;
bool check = false;
newt<VecDoub>(pt, check, &vecfunc);
}
}
Function newt is declared as
template <class T>
void newt(VecDoub_IO &x, Bool &check, T &vecfunc)
Why do I get the following compiler error?
error C2664: 'newt' : cannot convert parameter 3 from 'VecDoub (__cdecl *)(VecDoub_I)' to 'VecDoub &'
Solution
In calling newt
you explicitly specify that T
is VecDoub
(You specified newt<VecDoub>
) but you pass address of a function to it, so compiler can't convert your function to VecDoub&
. If you want a VecDoub&
in newt
then call vectfunc
and store it in a temporary variable and then pass that variable to the function(since in newt
last parameter is a reference to T
) but if you really need a function in newt
then why you write newt<VecDoub>(pt, check, &vecfunc)
while you can write newt(pt, check, &vecfunc)
and let C++ deduce the type for you? and beside that in order to receive functions in newt
do not get them by reference, instead get them by value, so newt
shall be declared as:
template <class T>
void newt(VecDoub_IO &x, Bool &check, T vecfunc)
Since functions are usually small objects or pointers this will work and do not decrease performance
OTHER TIPS
Because you're supposed to call the function and pass the return value as parameter, not the function itself.
newt<const VecDoub>(pt, check, vecfunc(something) );
I added the const
because the reference needs to be constant, otherwise the return value from vecfunc
can't bind to it, because it's a temporary.
To explain:
newt<VecDoub>(pt, check, &vecfunc);
attempts to call a function similar to
newt_VecDoub(VecDoub_IO &x, Bool &check, VecDoub &vecfunc);
The third parameter you attempt to pass is &vecfunc
which has the type VecDoub (__cdecl *)(VecDoub_I)
, so it obviously can't work.