2008-12-15 7 views
4

Tenir compte une classe de modèle comme:C++ déduction de « pointeur non de type à la fonction » modèle de classe paramètres

template<typename ReturnType, ReturnType Fn()> 
class Proxy 
{ 
    void run() 
    { 
     ReturnType ret = Fn(); 
     // ... do something ... 
    } 
}; 

// and a functions 
int fn1() { return 5; } 
float fn2() { return 5; } 

Cela peut être instancié en utilisant:

Proxy<int, &fn1> p1; 

Mais déclarant explicitement le type de valeur de retour semble inutile. Ce que je suis en train de réaliser est quelque chose comme:

someProxyInstantation<&fn1> p1; 
someProxyInstantation<&fn2> p2; 

Malheureusement, je ne suis pas C++ attendre et cela semble être un coin caché de la langue (au moins pour moi).

Si je pouvais obtenir du pointeur vers la fonction de son type - quelque chose comme: std :: tr1 :: result_of < & fn> :: Type // erreur 1 Erreur C2923: « std :: tr1: : result_of »: 'FN1' est pas un argument de type de modèle valide pour le paramètre '_Fty'

l'erreur est logique puisque le paramètre est un "type" du tout

C++ 0x a le decltype (& fn1) mais c'est dans des années.

Une façon de faire cela en C++ 03 (+ tr1)?

Restrictions: - Je ne veux pas passer le foncteur, f1 et f2 doivent rester des fonctions globales qui ont une valeur de retour (ne peut pas le déplacer au paramètre))

Répondre

6

Ce n » est pas. t possible en C++ 03. Si vous voulez passer un pointeur de fonction en tant que paramètre non-type, le compilateur doit connaître le type du paramètre. Vous devez donc fournir les pièces manquantes (dans ce cas, le type de retour). Vous pouvez donner au proxy le pointeur de fonction en tant que valeur lors de l'exécution, et lui fournir le type de celui-ci comme seul argument. Ensuite, vous pouvez écrire une fonction de générateur pour vous qui fait ce travail:

template<typename T> 
Proxy<T> make_proxy(T t) { return Proxy<T>(t); } 

Malheureusement, en cours C++, vous devez toujours donner le type afin d'assigner à une variable automatique:

Proxy<int(*)()> p = make_proxy(&fn1); 

Vous ne pouvez pas encore utiliser auto p = make_proxy(&fn1);. Notez que si vous souhaitez utiliser un type de fonction sur le côté gauche, vous devez changer la fonction de générateur pour fournir pas un type de pointeur de fonction:

template<typename T> 
Proxy<typename boost::remove_pointer<T>::type> make_proxy(T t) { 
    return Proxy<typename boost::remove_pointer<T>::type>(t); 
} 

Maintenant vous pouvez faire

Proxy<int()> p = make_proxy(&fn1); 

en utilisant la proxy, vous pouvez maintenant faire tout

doSomething(make_proxy(&fn1)); 

et si doSomething est basé sur un modèle ou autrement polymorphes, il vous ne aurez pas besoin de connaître le type exact de la fonction.

+0

Jusqu'à C++ 0x cela devra faire. –

Questions connexes