Comment déréférencer récursivement le pointeur (C ++ 03)?

J’essaie de déréférencer récursivement un pointeur en C ++.

Si un object qui n’est pas un pointeur est passé (ceci inclut les pointeurs intelligents), je souhaite simplement renvoyer l’object lui-même, par référence si possible.

J’ai ce code:

template static T &dereference(T &v) { return v; } template static const T &dereference(const T &v) { return v; } template static T &dereference(T *v) { return dereference(*v); } 

Mon code semble fonctionner correctement dans la plupart des cas, mais il se rompt lorsque des pointeurs de fonction sont donnés , car le déréférencement d’un pointeur de fonction entraîne le même type exact de pointeur de fonction, entraînant un débordement de stack.

Alors, comment puis-je “arrêter” le processus de déréférencement lorsque le type déréférencé a le même type que l’object d’origine?

Remarque:

Je vois que ma question a été marquée comme un doublon d’une question similaire qui utilise Boost; Cependant, j’ai besoin d’une solution sans Boost (ni aucune autre bibliothèque).


Exemple:

 template T &dereference(T &v) { return v; } template const T &dereference(const T &v) { return v; } template T &dereference(T *v) { return dereference(*v); } template void invoke(TCallback callback) { dereference(callback)(); } void callback() { } struct Callback { static void callback() { } void operator()() { } }; int main() { Callback obj; invoke(Callback()); // Should work (and does) invoke(obj); // Should also work (and does) invoke(&obj); // Should also work (and does) invoke(Callback::callback); // Should also work (but doesn't) invoke(&Callback::callback); // Should also work (but doesn't) invoke(callback); // Should also work (but doesn't) invoke(&callback); // Should also work (but doesn't) return 0; } 

Aucune dépendance, simple, ne devrait fonctionner sur MSVC-2008.

 template struct is_function { static char check(...); static double check(const volatile void*); // function pointers are not convertible to void* static T from; enum { value = sizeof(check(from)) != sizeof(char) }; }; template struct enable_if{}; template struct enable_if{typedef T type;}; template T& dereference(T &v){return v;} template const T& dereference(const T& v){return v;} template typename enable_if::value, T&>::type dereference(T* v){return dereference(*v);}