c ++ déduction de « pointeur non de type de fonction » paramètres du modèle de classe

StackOverflow https://stackoverflow.com/questions/368737

Question

Considérons une classe de modèle comme:

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).

: Quelque chose comme -

Si je pouvais obtenir du pointeur vers la fonction de son type      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 (et FN1), mais qui est loin des années.

Toute façon de le faire en 03 C ++ (+ 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))

Était-ce utile?

La solution

Ceci est impossible 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 de paramètre. Donc, vous devez fournir les pièces manquantes (dans ce cas, le type de retour). Vous pouvez donner le proxy le pointeur de fonction en tant que valeur lors de l'exécution, et de lui fournir le type de celui-ci comme le 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 utiliser encore 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 le proxy, vous pouvez maintenant faire juste

doSomething(make_proxy(&fn1));

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top