Function pointer list.

Is it possible to create an array or list of function pointers so that not all of them accept the same type of parameters?

Like
double F1(int x, int y) {return 1.0};
double F2(double x, double y) {return 2.0};

arr[1] = &F1;
arr[2] = &F2;
...

I've tried templates, but since I can't instantiate a class defined with a template without specifying a type, I can't get a non homogeneous list of function pointers...

I thought in theory this should be possible, because the array will only store addresses. Of course, since if this array could be built you would't be able to know a priori the type of the arguments of each function, I guess the restriction is somewhat coherent.

Anyway, I need to store a list of distance functions, some of them accepting doubles, some of them accepting dates, or integers... If someone has a tip about how to manage that without tayloring the functions so that all of them accept doubles, I'd be very grateful.

Thank you in advance.
You could try this:
1
2
3
4
5
6
7
8
9
struct distance_function{
    union{
        void* function;//any pointer can be assigned to void*

        int (*f_int)(int, int);//these are here so that you don't have to cast void*
        double (*f_double)(double, double); //to appropriate function to use it.
    };
    int type;//you need a way to know which function is stored
};


However, whatever problem you're facing, I don't think this is a good solution. What exactly are you trying to do?
I have an input file with a list of sets of several non homogeneous coordinates (angle, date, time, ...) and each of the type of coordinate has a pre-defined distance).

I have to work with a function of the distances between the coordinates of two of those sets, (like:
f(dist(date1,date2),dist(time1,time2),dist(angle1,angle2),...) and in theory the user ought to be able to alter the order of the data and to provide a function distance for each coordinate.

I'll try your approach, maybe that is what I need :)

Thank you very much.
Maybe you could make a base coordinate class that contains a pure virtual "distance" function?
About the array of function pointers, I was thinking something along the lines of hamsterman,
but using a class/struct with various overloads for the function call operator1.
You could then have a vector or array of this class.


1 we would be using functions rather than function pointers


EDIT: come to think of it - you wouldn't need an array of the class, just one object/instance, or maybe just an on-the-spot temprary would do.
Last edited on
How about 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <exception>
#include <cmath>
using namespace std;

class BadCast: public exception
{
    const char * what() const throw()
        {return "bad cast!";}
};

class BaseFuncPtr
{
public:

    virtual ~BaseFuncPtr(){}

    template <class ArgType>
    double operator()(ArgType a1, ArgType a2);

private:

    virtual void * get_function()=0;
    virtual void * get_type()=0;
};

template <class ArgType>
class FuncPtr: public BaseFuncPtr
{
public:

    typedef double (*FPTR)(ArgType,ArgType);

    FuncPtr(FPTR f):function(f){}
    static void * get_type_static() {return &type;}

private:

    FPTR function;
    static int type;

    void * get_function() {return (void*)function;}
    void * get_type() {return &type;}
};

template <class ArgType>
int FuncPtr<ArgType>::type;

template <class ArgType>
double BaseFuncPtr::operator()(ArgType a1, ArgType a2)
{
    if (FuncPtr<ArgType>::get_type_static()==get_type())
    {
        typename FuncPtr<ArgType>::FPTR ptr;
        ptr=(typename FuncPtr<ArgType>::FPTR)get_function();

        return ptr(a1,a2);
    }

    throw(BadCast());
}

/////////////////////////////////////////////////////////////////

double dist_int(int i1, int i2) {return abs(i1-i2);}
double dist_double(double d1, double d2) {return abs(d1-d2);}

enum {INTEGER=0, DOUBLE=1};

int main()
{
    BaseFuncPtr* func_table[2];
    FuncPtr<int> f1(dist_int);
    FuncPtr<double> f2(dist_double);

    func_table[0]=&f1;
    func_table[1]=&f2;

    int i1, i2;
    cout << "enter 2 ints:\n";
    cin >> i1 >> i2;

    cout << "distance: " << (*func_table[INTEGER])(i1,i2) << endl;

    double d1, d2;
    cout << "\nenter 2 doubles:\n";
    cin >> d1 >> d2;

    cout << "distance: " << (*func_table[DOUBLE])(d1,d2) << endl;

    cout << "\nlet's try something bad..." << endl;
    try {(*func_table[INTEGER])(d1,d2);}
    catch (exception & e) {cout << e.what() << endl;}

    cin.get();
    cin.get();
    return 0;
}
op's design is solved in c++ by polymorphism
Which is exactly what I did... I made the derived class a template so that I don't have to do something like this:

1
2
3
4
class BaseFuncPtr {/*...*/};
class FuncPtrInt: public BaseFuncPtr {/*...*/};
class FuncPtrDouble: public BaseFuncPtr {/*...*/};
//etc... 
Topic archived. No new replies allowed.