Function Pointers and void*

May 23, 2011 at 7:05pm
I'm trying to initialize an array of function pointers.

my typedef:

typedef void (*fPtr) (void*);

Array/initializers:

fPtr p[4] = {palindromeCheck, postFix, battle, fileLoader};

Use of fptr[]:

void funUI(void (*f[]) (void * ), void * input);

an example of one of the functions:

void palindromeCheck(string* str)

compiler error:

\main.cpp|29|error: invalid conversion from 'void (*)(std::string*)' to 'void (*)(void*)'|


I thought void* were used as generic pointers that could be used as any type.
I'm new to the whole concept so maybe im way off but this seems like it should work to me. Any ideas? I'd be happy to post more code.
Last edited on May 24, 2011 at 6:47am
May 23, 2011 at 7:40pm
True that void* can point to anything, but the error is telling you something else: "I cannot just validate your use of this function like this because there is no way I am going to convert your pointer to string to a pointer of anything."

Although I rarely ever use function pointers, I would imagine that an explicit cast would solve the problem:

fPtr p[] = { (fPTR)palindromeCheck, postFix, battel, fileLoader };

And yes, always use [code]//Code shows formatted here! [/code] tags to show code.
May 23, 2011 at 8:45pm
closed account (D80DSL3A)
I got it to work but I had to write the functions to take a void* as an argument then perform the needed cast within each function.
The following actually works:
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
#include <string>
#include <vector>
#include <iostream>
using namespace std;

// 3 trivial functions for the test
void showStr(void* pv)
{
	string* pStr = (string*)pv;
	cout << *pStr << endl;
}
void showDbl(void* pv)
{
	double* pDbl = (double*)pv;
	cout << *pDbl << endl;
}
void showVec(void* pv)
{
	vector<int>* pVec = (vector<int>*)pv;
	for( vector<int>::iterator it = pVec->begin(); it != pVec->end(); ++it)
		cout << *it << " ";
	cout << endl;
}

int main()
{
	// setup some data
	string s = "A few words.";
	double d = 3.1415;
	vector<int> ivec; ivec.push_back(1); ivec.push_back(2); ivec.push_back(3);

	// array of void*'s to the data
	void* pv[3] = { (void*)&s, (void*)&d, (void*)&ivec };

	// array of function pointers
	void (*pf[3])(void*) = {showStr, showDbl, showVec};

	// call the functions
	for(int i=0; i<3; ++i)
		pf[i]( pv[i] );
	cout << endl;
	return 0;
}

Output is as expected:

A few words.
3.1415
1 2 3
May 23, 2011 at 9:52pm
I suppose that would be a C way of doing things and templates/function overloading would be a C++ solution ???
May 24, 2011 at 4:09am
Thanks guys. I ended up coming to the same solution as fun2code. it works great thank you =D

And i was just doing this as a fun way to implement a UI for one of my programming projects in school. and get some function pointer practice.

Now I'm going to try to figure out how a functor works =D

oh ya.. and thanks for the input about "//using the code format " =D
Last edited on May 24, 2011 at 6:49am
May 24, 2011 at 6:14am
Here's what I came up with if anyone is interested:
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
void SSTool::funUI(void (*f[]) (void*),  string m[], int numOfStr = 0, int numOfInt = 0,
                    int numOfFloat = 0, int numOfDoub = 0, int numOfBool = 0)
{
  bool done = false;
  while(!done)
    {
      int strTotal = numOfStr;
      int intTotal = numOfInt + numOfStr;
      int floatTotal = numOfInt + numOfStr + numOfFloat;
      int doubleTotal = numOfInt + numOfStr + numOfFloat + numOfDoub;
      int boolTotal = numOfInt + numOfStr + numOfFloat + numOfDoub + numOfBool;
      string strInput;
      int intInput;
      float floatInput;
      double doubleInput;
      bool boolInput;

      int choice = menu(m, boolTotal + 1);
      if(choice <= numOfStr)
      {
          for(int i = 0; i <= strTotal; i++)
          {
              if(i == choice - 1)
              {
                  cout << "Input: (string)" << endl;
                  strInput = reader.readString();
                  f[i](&strInput);
                  pause();
              }

          }
      }
      else if(choice <= (intTotal))
      {
          for(int i = strTotal; i < intTotal; i++)
          {
              if( i == choice - 1)
              {
                  cout << "Input: (int)" << endl;
                  intInput = reader.readInt();
                  f[i](&intInput);
                  pause();
              }

          }
      }
      else if(choice <= (floatTotal))
      {
          for(int i = intTotal; i < floatTotal; i++)
          {
              if( i == choice - 1)
              {
                  cout << "Input: (float)" << endl;
                  floatInput = reader.readFloat();
                  f[i](&floatInput);
                  pause();
              }

          }
      }
      else if(choice <= (doubleTotal))
      {
          for(int i = floatTotal; i < doubleTotal; i++)
          {
              if( i == choice - 1)
              {
                  cout << "Input: (double)" << endl;
                  doubleInput = reader.readDouble();
                  f[i](&doubleInput);
                  pause();
              }

          }
      }
      else if(choice <= (boolTotal))
      {
          for(int i = doubleTotal; i < boolTotal; i++)
          {
              if( i == choice - 1)
              {
                  cout << "Input: (bool)" << endl;
                  boolInput = reader.readBool();
                  f[i](&doubleInput);
                  pause();
              }

          }
      }
      else
        done = true;
    }
}

Last edited on May 24, 2011 at 6:15am
Topic archived. No new replies allowed.