Funciton with function pointer argument

O

oalfishcivil

I have a function double solver(double (*pf)(double), double tol)
However, it would be nice if solver could work for function
double func(double x,double para) since the codes are similar.
How could I do that? Thanks
Yuefei
 
V

Vladyslav Lazarenko

I have a function  double solver(double (*pf)(double), double tol)
However, it would be nice if solver could work for function
double func(double x,double para) since the codes are similar.
How could I do that? Thanks
Yuefei

1) Create the base function: "double solver(double x, double para)"
2) Move implementation from "double solver(double (*pf)(double),
double tol)" except invocation of the function pointed by "pf" to that
function.
3) Change "double solver(double (*pf)(double), double tol)" function
to call "double solver(double x, double para)" with x = result of
invocation of the function pointed by "pf".
 
V

Victor Bazarov

oalfishcivil said:
I have a function double solver(double (*pf)(double), double tol)
However, it would be nice if solver could work for function
double func(double x,double para) since the codes are similar.
How could I do that? Thanks
Yuefei

I agree with Vladislav. Move, rename, invoke, take the return value,
and invoke again. And if you want to see C++ code, so do we. Show us
yours and we'll show you ours. Good luck!

V
 
A

Andrey Tarasevich

oalfishcivil said:
I have a function double solver(double (*pf)(double), double tol)
However, it would be nice if solver could work for function
double func(double x,double para) since the codes are similar.
How could I do that? Thanks

It is hard to figure out what is it exactly that you need, but at the
first sight it looks like you are looking for a "closure" functionality,
i.e. you want to convert a 'double (*)(double, double)' function pointer
to a 'double (*)(double)' function pointer by pre-assigning a fixed
second parameter value. Unfortunately, there's no elegant portable way
to do it in C++ as long as you stick with function pointers.

A possible workaround is to provide a wrapper function for your 'double
func(double x, double para)' and specify the 'para' value through a
global variable

double g_para;

double func_wrapper(double x) {
return func(x, g_para);
}

and then use 'func_wrapper' in calls to 'solver', not forgetting to set
the 'g_para' to the proper value in advance. This is, of course, a
rather inelegant solution, since it relies on a global variable. It is
not reentrant, which severely limits is usefulness.

P.S. Of course, if you can get rid of the callback entirely, as
Vladyslav suggested, it would be the right way to go. But if you really
need the callback, then you are pretty much stuck with the above.
 
A

Andrey Tarasevich

Vladyslav said:
1) Create the base function: "double solver(double x, double para)"
2) Move implementation from "double solver(double (*pf)(double),
double tol)" except invocation of the function pointed by "pf" to that
function.
3) Change "double solver(double (*pf)(double), double tol)" function
to call "double solver(double x, double para)" with x = result of
invocation of the function pointed by "pf".

Usually, a callback-based interface implies that the callback function
needs to be called repeatedly from the 'solver' function, each time with
different arguments and different results. In general case there's no
way to replace all these invocations with a single invocation in
advance. If that were possible, there probably wouldn't be a callback
there in the first place.
 
A

Andrey Bulat

Usually, a callback-based interface implies that the callback function
needs to be called repeatedly from the 'solver' function, each time with
different arguments and different results. In general case there's no
way to replace all these invocations with a single invocation in
advance. If that were possible, there probably wouldn't be a callback
there in the first place.

I can propose for discussion following simple sample:

class Functor2
{
public:
Functor2(int A, int B): a(A),b(B){}
int a;
int b;
virtual int operator()()
{
return b;
}
};

class Functor1: public Functor2
{
public:
Functor1(int A): Functor2(A, 0){}
virtual int operator()()
{
return a;
}
};

int solver(Functor2* p, int d)
{
return (*p)() + d;
}

int main()
{
Functor1 f1(5);
Functor2 f2(3,2);
int ret;
ret = solver(&f1, 7);
ret = solver(&f2, 7);
}

As for me it is more valuable construction versus global variable (and
much more readeble).
(It works on VS2008)

Best wishes
Andrey Bulat
 
A

Andrey Tarasevich

Andrey said:
...
I can propose for discussion following simple sample:

class Functor2
> ...
> As for me it is more valuable construction versus global variable

Well, that's what I meant by "as long as you stick with function
pointers" in my other message ("there's no elegant portable way
to do it in C++ as long as you stick with function pointers")

Switching to functors would turn all this into a completely different
story. Functors would let one to implement "closure" rather easily, but
the main question here is whether such a switch is a possibility in the
OP's case.
 
O

oalfishcivil

I can propose for discussion following simple sample:

class Functor2
{
public:
        Functor2(int A, int B): a(A),b(B){}
        int a;
        int b;
        virtual int operator()()
    {
                return b;
    }

};

class Functor1: public Functor2
{
public:
        Functor1(int A): Functor2(A, 0){}
        virtual int operator()()
    {
        return a;
    }

};

int solver(Functor2* p, int d)
{
        return (*p)() + d;

}

int main()
{
    Functor1 f1(5);
    Functor2 f2(3,2);
    int ret;
    ret = solver(&f1, 7);
    ret = solver(&f2, 7);

}

As for me it is more valuable construction versus global variable (and
much more readeble).
(It works on VS2008)

Best wishes
Andrey Bulat

Really appreciate your example and others' suggestions. I am writing a
code use bisection method to find roots in given bounds for
functions like double func(double x) or double func(double x,double
para). Since I have several different such functions, I want to write
a bisection method function which can take this functions as argument
instead of adding the bisection method in each function which will
produce a lot more repetitive codes. I think your method here would
work for me although it's not that elegant(not your fault). Thanks
Yuefei
 
V

Vladyslav Lazarenko

Really appreciate your example and others' suggestions. I am writing a
code use bisection method to find roots in given bounds for
functions like double func(double x) or double func(double x,double
para). Since I have several different such functions, I want to write
a bisection method function which can take this functions as argument
instead of adding the bisection method in each function which will
produce a lot more repetitive codes. I think your method here would
work for me although it's not that elegant(not your fault). Thanks
Yuefei

Just a friendly suggestion - use templates instead of polymorphism.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top