Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Funciton with function pointer argument

0 views
Skip to first unread message

oalfishcivil

unread,
Mar 31, 2009, 12:42:12 PM3/31/09
to
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

Vladyslav Lazarenko

unread,
Mar 31, 2009, 1:07:34 PM3/31/09
to

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".

Victor Bazarov

unread,
Mar 31, 2009, 1:13:27 PM3/31/09
to

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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Andrey Tarasevich

unread,
Mar 31, 2009, 1:47:03 PM3/31/09
to

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.

--
Best regards,
Andrey Tarasevich

Andrey Tarasevich

unread,
Mar 31, 2009, 1:50:45 PM3/31/09
to
Vladyslav Lazarenko wrote:
> On Mar 31, 12:42 pm, oalfishcivil <yuefei...@gmail.com> wrote:
>> 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
>
> 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.

Andrey Bulat

unread,
Mar 31, 2009, 6:16:37 PM3/31/09
to
On Mar 31, 8:50 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:

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

Andrey Tarasevich

unread,
Mar 31, 2009, 6:52:12 PM3/31/09
to
Andrey Bulat wrote:
> ...

> 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.

oalfishcivil

unread,
Apr 1, 2009, 1:05:05 AM4/1/09
to

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

Vladyslav Lazarenko

unread,
Apr 1, 2009, 8:41:15 AM4/1/09
to

Just a friendly suggestion - use templates instead of polymorphism.

Victor Bazarov

unread,
Apr 1, 2009, 5:14:06 PM4/1/09
to
Vladyslav Lazarenko wrote:
> [..]

> Just a friendly suggestion - use templates instead of polymorphism.

As if they can actually be freely substituted...

0 new messages