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.
You can use pointers to member functions in the same manner as pointers to functions.
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.
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.
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.
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.
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(); };
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With