Specialization of a function

May 22, 2011 at 11:34am
Hi,

I am writing some scientific code. I have created a function "quadrature" which integrates over a triangle a given function provided in argument through a pointer function, basically:

double quadrature(double (* func)(double, double)) { return blah;}

Now, in an other function I want to use a pass in argument of quadrature a function like:

double function_blah(int, double, double)

by specifying the 'int' beforehand.
How to create a function pointer like that? Can I write:

double (*specialized_function)(double, double) = &(function_blah(3, double, double));

If I can't, what could be a way around this?
Thanks for your help!
May 22, 2011 at 11:43am
Your pointer must also be to a function double (*)(int, double, double).

I am pretty sure a function must exactly much the function pointer in arguments for its address to be assigned to the pointer.

In then you wanted to use a function with just the two double arguments, you could just give it an unnamed and unused integer parameter to ensure compatibility with the pointer:
1
2
3
4
double foo(int, double x, double y)
{
   // etc
}
May 22, 2011 at 11:56am
Thanks a lot for you answer. However, there is still something unclear to me:
according to you, I could write:
 
double (*specialized_function)(int, double, double) = &(function_blah(3, double, double));

Is that right?

and use specialized_function as an argument of quadrature as long as quadrature has the prototype:
 
double quadrature(double (* func)(int, double, double)) { return blah;}

Would it be possible?
Cheers!
May 22, 2011 at 12:02pm
I don't see why not. When it doubt, compile and see for yourself ;)

And as I said, if you want to use your quadrature function with a function taking just two double arguments, you just have to remember to give that function an unused integer parameter so it matches the prototype.
May 22, 2011 at 12:02pm
It doesn't work like that.
However, you can use boost::bind for this.

Example:

1
2
3
4
template <class BinaryFunction> double quadrature(BinaryFunction func) {return func(0,42);}
double function_blah(int, double, double) { ... }

quadrature(boost::bind(function_blah,3,_1,_2));
May 22, 2011 at 12:03pm
If you want to bind arguments to a function, you'll have to do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

int add(int a, int b) { return a+b; }
int mul(int a, int b) { return a*b; }

struct Function
{
    typedef int (*FPTR)(int, int);

    FPTR f;
    int a;

    Function(FPTR f_, int a_):
        f(f_), a(a_) {}

    int operator()(int b) { return f(a,b); }
};

int main()
{
    Function add_5(add,5);

    std::cout << add_5(2) << std::endl;
    std::cout << add_5(3) << std::endl;

    Function mul_3(mul,3);

    std::cout << mul_3(3) << std::endl;
    std::cout << mul_3(4) << std::endl;

    return 0;
}

EDIT: I guess boost::bind would work too.
Last edited on May 22, 2011 at 12:04pm
May 22, 2011 at 12:09pm
Athar wrote:
It doesn't work like that.

What did I do wrong? I don't see it...
Last edited on May 22, 2011 at 12:10pm
May 22, 2011 at 12:10pm
Thanks a lot to you guys for your help!
May 22, 2011 at 12:34pm
What did I do wrong? I don't see it...

Well, not naming a parameter has no effect on anything, you'll still have to pass three parameters.
And in particular, it would require changing the type of function quadrature takes as a parameter. That way you actually spilled the specialization onto the "general case", even though the "general case" probably has no idea what to pass for the first parameter.

Something like double (*specialized_function)(int, double, double) = &(function_blah(3, double, double)); won't work.
May 22, 2011 at 1:08pm
@Athar Heh, I feel stupid now... Of course that doesn't work :/ I'm not sure why, but it seems that earlier I didn't quite register the fact that the OP was passing arguments to the function on the line where he took its address :S

@JCS It looks like I gave you stupid advice - sorry about that...
Last edited on May 22, 2011 at 1:17pm
Topic archived. No new replies allowed.