C ++ Est-il possible d’avoir un pointeur de fonction générique?

En C ++, est-il possible de créer une sorte de pointeur de fonction générique qui pointe vers une fonction qui renvoie un pointeur sur un type quelconque et ne prend aucun argument?

Par exemple, un type de pointeur pouvant pointer vers les deux éléments suivants:

int* funcInt(){ int* i = new int; *i = 5; return i; } char* funcChar(){ char* c = new char; *c = 'a'; return c; } 

Évidemment, le ci-dessous est valide:

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

Mais est-il possible de faire quelque chose comme ceci (cela donne une erreur de compilation pour le moment):

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

Actuellement, le code ci-dessus génère l’erreur suivante:

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

Est-il possible de lancer les fonctions funcPointerA et B en C et D?

C’est ainsi que les pointeurs sur les deux types de fonctions (et d’autres qui renvoient un pointeur sur un type quelconque sans prendre d’argument) peuvent être stockés ensemble dans un seul vecteur.

La norme ne permet pas une telle chose. Vous pouvez ou ne pouvez pas vous en sortir en jetant votre pointeur de fonction sur void* (*)() . En C ++, il existe des solutions conformes aux normes. Voici un exemple simple pré-C ++ 11:

 struct MyFunc { virtual void* operator()() = 0; virtual ~Myfunc(){} }; template  struct MyfuncImpl { typedef T TFunc(); MyfuncImpl (TFunc* func) : m_func(func) {} void* operator()() { return m_func(); } private: TFunc* m_func; }; 

Vous pouvez maintenant stocker shared_ptr dans votre vecteur.

Une solution bien plus intéressante en C ++ 11 pourrait ressembler à ceci:

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

Est-il possible de lancer les fonctions funcPointerA et B en C et D?

Oui, vous pouvez explicitement convertir un type de pointeur de fonction en un autre type:

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

Mais le fait d’appeler le résultat de la conversion est un comportement indéfini, vous devez tout d’abord le remettre à son type d’origine. Si vous pouvez enregistrer le type d’origine et organiser le renvoi du pointeur vers ce type d’origine, votre code peut fonctionner.