Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 333
jtedit Avatar asked May 12 '13 15:05

jtedit


People also ask

Can we create a pointer to a member function?

You can use pointers to member functions in the same manner as pointers to functions.

What is generic function in C?

Generic functions are functions declared with one or more generic type parameters. They may be methods in a class or struct , or standalone functions. A single generic declaration implicitly declares a family of functions that differ only in the substitution of a different actual type for the generic type parameter.

Are function names pointers in C?

In C, like normal data pointers (int *, char *, etc), we can have pointers to functions. Following is a simple example that shows declaration and function call using function pointer.

What in C# is similar to a function pointer in C or C++?

A delegate is behaviorally similar to a C function pointer (or Delphi closure), but delegates can hold multiple methods, as well as hold the instance associated with each nonstatic method. In addition, delegates, like all other C# constructs used outside unsafe blocks, are type-safe and secure.


2 Answers

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.

like image 70
Jonathan Wakely Avatar answered Oct 28 '22 15:10

Jonathan Wakely


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(); };
}
like image 27
n. 1.8e9-where's-my-share m. Avatar answered Oct 28 '22 16:10

n. 1.8e9-where's-my-share m.