By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
 440,496 Members | 1,528 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,496 IT Pros & Developers. It's quick & easy.

# matrix of function pointers

 P: n/a Hi all, I'm in need of a matrix of function pointers, and to be honest. No 'nice' solution has been found yet on that big big internet. It is possible to declare a matrix of function pointers in the following way void (*f[2][2])(int); But I want to know how I can declare this only using double pointers. like an array double **a; a = new double *[2]; for (int i = 0; i < 2; i++) a[i] = new double [2]; I would like to know this, because I have in my code something which is similar like below, and i want it to work. The problem is, that during compiling i obtain the following error. cannot convert 'void (* (*)[2])(int)' to 'void (***)(int)' for argument '1' to 'void pm_funcion(void (***)(int), int)' cannot convert 'void (* (*)[3])(int)' to 'void (***)(int)' for argument '1' to 'void pm_funcion(void (***)(int), int)' thanks in advance klaas //function void pm_function(void (***f) (int), int dim) { for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) f[i][j](5); } int main(void) { void (*f[2][2])(int); void (*g[3][3])(int); // I want this to work, but it doesn not! See error above message pm_function(f,2); pm_function(g,3); } Mar 20 '06 #1
Share this Question
8 Replies

 P: n/a Maybe the following code would help: typedef void (*fnptr)(int); typedef fnptr** fnptr_mtrx; fnptr_mtrx matrix = ... Mar 20 '06 #2

 P: n/a "Klaas Vantournhout" wrote in message news:dv**********@gaudi2.UGent.be Hi all, I'm in need of a matrix of function pointers, and to be honest. No 'nice' solution has been found yet on that big big internet. It is possible to declare a matrix of function pointers in the following way void (*f[2][2])(int); But I want to know how I can declare this only using double pointers. like an array double **a; a = new double *[2]; for (int i = 0; i < 2; i++) a[i] = new double [2]; I would like to know this, because I have in my code something which is similar like below, and i want it to work. The problem is, that during compiling i obtain the following error. cannot convert 'void (* (*)[2])(int)' to 'void (***)(int)' for argument '1' to 'void pm_funcion(void (***)(int), int)' cannot convert 'void (* (*)[3])(int)' to 'void (***)(int)' for argument '1' to 'void pm_funcion(void (***)(int), int)' thanks in advance klaas //function void pm_function(void (***f) (int), int dim) { for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) f[i][j](5); } int main(void) { void (*f[2][2])(int); void (*g[3][3])(int); You realise of course that you have never initialised these function pointers to point to anything. // I want this to work, but it doesn not! See error above message pm_function(f,2); pm_function(g,3); } Your problem is not specifically with function pointers. You would have the same problem with arrays of ints, e.g., the following won't compile for the same reason. void pm_function(int **pptr, int dim) { for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) cout << pptr[i][j]; } int main() { int arraytwo[2][2]; int arraythree[3][3]; pm_function(arraytwo,2); pm_function(arraythree,3); return 0; } Array names and pointers are only (more or less) interchangeable when the array is one dimensional (in the sense of having a single subscript). For two and more dimensions (in the sense of two or more subscripts) they are quite different. To illustrate, if pptr points to an int pointer, then pptr+1 is an address that is sizeof(int*) greater than pptr. By contrast, using the definition of arraythree given above, arraythree+1 yields an address that is 3*sizeof(int) greater than the address of arraythree. The difference is because pptr points to an int* pointer, whereas arraythree points to a row of three ints. To prove it, run the following code: int main() { int x; int *ptr = &x; int **pptr = &ptr; cout << "pptr address is " << pptr << '\n'; cout << "pptr+1 address is " << pptr+1 << '\n'; int arraythree[3][3]; cout << "arraythree address is " << arraythree << '\n'; cout << "arraythree+1 address is " << arraythree+1 << '\n'; return 0; } If you want to pass 2-dimensional arrays to a function, then you need to a different function for each different column count. Templates can help here. -- John Carson Mar 20 '06 #3

 P: n/a >> //function void pm_function(void (***f) (int), int dim) { for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) f[i][j](5); } int main(void) { void (*f[2][2])(int); void (*g[3][3])(int); You realise of course that you have never initialised these function pointers to point to anything. Yes I do ;-) // I want this to work, but it doesn not! See error above message pm_function(f,2); pm_function(g,3); } Your problem is not specifically with function pointers. You would have the same problem with arrays of ints, e.g., the following won't compile for the same reason. If you want to pass 2-dimensional arrays to a function, then you need to a different function for each different column count. Templates can help here. I am indeed aware of this. That is why I would like to define my matrix of function pointers using dynamical allocation using the new operator. This should sort that problem out and let me use a double pointer in the function call. The answer given by benben is indeed a solution. But I was wondering if you could do it without defining a new type. Already thanks for your swift response. klaas Mar 20 '06 #4

 P: n/a I think you should go back to basics, first the work out the pointers to functions: #ifdef HAVE_CONFIG_H #include #endif #include #include using namespace std; //----------------------------------------------------------------------------- // define the type typedef void (*Tpointer2Function)(int); // define the array with 3 elements Tpointer2Function ArrayOfFunctions[3]; //----------------------------------------------------------------------------- void function1(int a) { cout << "function 1 = " << a << endl; } //----------------------------------------------------------------------------- void function2(int a) { cout << "function 2 = " << a << endl; } //----------------------------------------------------------------------------- void function3(int a) { cout << "function 3 = " << a << endl; } //----------------------------------------------------------------------------- int main(int argc, char *argv[]) { // assign the functions you want to call to the array ArrayOfFunctions[0] = function1; ArrayOfFunctions[1] = function2; ArrayOfFunctions[2] = function3; // iterate thru the array for (int i=0; i <=2; i++) { ArrayOfFunctions[i](i); } return EXIT_SUCCESS; } //----------------------------------------------------------------------------- Once you've done that you could go and have a dynamic array (see Bruce Eckel's 'thinking in c++' 2nd edition - "Arrays of pointers to functions" section - with minor modifications): #include #include using namespace std; //----------------------------------------------------------------------------- // A macro to define dummy functions - Bruce's functions have no int parameter; #define DF(N) void N(int a) { cout << "function " #N " called with parameter " << a << endl; } DF(a); DF(b); DF(c); DF(d); DF(e); DF(f); DF(g); void (*func_table[])(int) = {a, b, c, d, e, f, g}; //----------------------------------------------------------------------------- int main(int argc, char *argv[]) { while (true) { char c, cr; cout << "press a key from 'a' to 'g' or 'q' to quit" << endl; cin.get(c); cin.get(cr); // second one for CR // another alteration LValues are better there so you don't get assignments // rather than comparisons if ('q'== c) break; if (c < 'a' || c > 'g') continue; (*func_table[c - 'a'])(101); } return EXIT_SUCCESS; } //----------------------------------------------------------------------------- Mar 20 '06 #5

 P: n/a benben wrote: Maybe the following code would help: typedef void (*fnptr)(int); typedef fnptr** fnptr_mtrx; fnptr_mtrx matrix = ... Thanks benben for the swift response, But is this possible without redefining a new type? In your declaration fnptr_mtrx is indeed of the type void (***)(int); using your declartion I would be able to do fnptr_mtrx = new fnptr *[n]; for (int i = 0; i < n; i++) fnptr[i] = new fnptr [m]; to construct an n x m function pointer matrix, but is it possible to write something like void (***g)(int); g = new void (**)(int) *[5]; or anything like that? (the above does not work) klaas Mar 20 '06 #6

 P: n/a "Klaas Vantournhout" wrote in message news:dv**********@gaudi2.UGent.be I am indeed aware of this. That is why I would like to define my matrix of function pointers using dynamical allocation using the new operator. This should sort that problem out and let me use a double pointer in the function call. The answer given by benben is indeed a solution. But I was wondering if you could do it without defining a new type. Already thanks for your swift response. klaas A typedef does not introduce a new type. It is simply an alias for a type. You can do dynamic allocation of function pointers without using a typedef, but it is pointlessly difficult to do so. Just for the record: #include using namespace std; // function to which function pointers will point template void func(int x) { cout << n*x << '\n'; } // your (modified) function void pm_function(void (*(*(*f)))(int), int dim) { for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) f[i][j](5); } int main() { // dynamic pointer allocation void (*(*(*g)))(int) = new (void (*(*[3]))(int)); for(int i=0; i<3; ++i) g[i] = new (void (*[3])(int)); // initialise function pointers for(int i=0; i<3; ++i) { for(int j=0; j<3; ++j) { switch(i) { case 0: g[i][j]=&func<0>; break; case 1: g[i][j]=&func<1>; break; case 2: g[i][j]=&func<2>; break; } } } // test your function pm_function(g,3); // cleanup for(int i=0; i<3; ++i) delete[] g[i]; delete[] g; return 0; } If you think this is good code, then we have very different ideas of what constitutes good code. -- John Carson Mar 20 '06 #7

 P: n/a > A typedef does not introduce a new type. It is simply an alias for a type. Indeed, my mistake there You can do dynamic allocation of function pointers without using a typedef, but it is pointlessly difficult to do so. Just for the record: void (*(*(*g)))(int) = new (void (*(*[3]))(int)); for(int i=0; i<3; ++i) g[i] = new (void (*[3])(int)); If you think this is good code, then we have very different ideas of what constitutes good code. Why should this not be good code? I dislike the use of typedef because it makes things sometimes unreadable. It is to my opinion only usefull when you have an extreme long annoying type which you have to declare multiple times. Here this is not the case, you can see immediately of what type 'g' is. And it is not much more difficult then using a typedef. The initialisation is done in the same way. Or did you mean something else? I used this in my code because I could reduce 300 lines of code to only 20 with this. Removed a big mixture of case and if conditions which was totally unreadable. And also the size of the matrix depends on the initial conditions of my program. Thanks again for the answer. You made my day! klaas Mar 21 '06 #8

 P: n/a "Klaas Vantournhout" wrote in message news:dv**********@gaudi2.UGent.be A typedef does not introduce a new type. It is simply an alias for a type. Indeed, my mistake there You can do dynamic allocation of function pointers without using a typedef, but it is pointlessly difficult to do so. Just for the record: void (*(*(*g)))(int) = new (void (*(*[3]))(int)); for(int i=0; i<3; ++i) g[i] = new (void (*[3])(int)); If you think this is good code, then we have very different ideas of what constitutes good code. Why should this not be good code? I dislike the use of typedef because it makes things sometimes unreadable. It is to my opinion only usefull when you have an extreme long annoying type which you have to declare multiple times. Here this is not the case, you can see immediately of what type 'g' is. I doubt that 1 in 100 C++ programmers can "see immediately what type g is". I couldn't do so myself if I hadn't written the code. Compare: typedef void (*FnPtr)(int); FnPtr **g = new FnPtr*[3]; for(int i=0; i<3; ++i) g[i] = new FnPtr[3]; Once you make the typedef, this looks just like what you would do if you had an array of ints or doubles. It is familiar and easy to comprehend. -- John Carson Mar 23 '06 #9

### This discussion thread is closed

Replies have been disabled for this discussion.