jtedit
jtedit

Reputation: 1470

C++ Is it possible to have a generic function pointer?

In C++ is it possible to make some sort of generic function pointer that points to any function that returns a pointer to some type and takes no arguments?

Eg, one type of pointer that can point to both of the following:

int* funcInt(){
    int* i = new int;
    *i = 5;
    return i;
}

char* funcChar(){
    char* c = new char;
    *c = 'a';
    return c;
}

Obviously the below is valid:

int* (*funcPointerA)() = funcInt;
char* (*funcPointerB)() = funcChar;

But is it possible to do something like the following (it gives a compile error at the moment):

void* (*funcPointerC)() = funcInt;
void* (*funcPointerD)() = funcChar;

Currently the above code gives the following error:

error: invalid conversion from 'int* (*)()' to 'void* (*)()'
error: invalid conversion from 'char* (*)()' to 'void* (*)()'

Is there any way to cast the funcPointerA and B to C and D?

This is so pointers to both types of functions (and others that return a pointer to some type while taking no arguments) can be stored together in a single vector.

Upvotes: 10

Views: 11206

Answers (2)

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

The standard does not allow such thing. You may or may not be able to get away with casting your function pointer to void* (*)(). In C++ there are standard-conforming solutions. Here is a simple pre-C++11 one:

struct MyFunc
{
  virtual void* operator()() = 0;
  virtual ~Myfunc(){}
};

template <typename T>
struct MyfuncImpl
{
  typedef T TFunc();
  MyfuncImpl (TFunc* func) : m_func(func) {}
  void* operator()() { return m_func(); }
 private:
  TFunc* m_func;
};

Now you can store shared_ptr<Myfunc> in your vector.

A much nicer solution in C++11 could look like this:

template <typename T>
std::function<void*()> castToVoidFunc (T* (*func)())
{
  return [=](){ return func(); };
}

Upvotes: 8

Jonathan Wakely
Jonathan Wakely

Reputation: 171313

Is there any way to cast the funcPointerA and B to C and D?

Yes, you can explicitly cast one type of function pointer to another type:

void* (*funcPointerC)() = reinterpret_cast<void*(*)()>(funcInt);

But it is undefined behaviour to call the result of the cast, you must cast it back to its original type first. If you can record the original type and arrange for the pointer to be cast back to that original type then your code can work.

Upvotes: 9

Related Questions