9
votes

Extraire le type de retour d'une fonction sans l'appeler (à l'aide de modèles?)

Je cherche un moyen en C ++ pour extraire le type de retour d'une fonction (sans l'appeler). Je suppose que cela nécessitera une magie de modèle. XXX

Je cherche actuellement comment Magic_Template pourrait être mis en œuvre, mais n'a pas trouvé de solution jusqu'à présent.

Des idées?


0 commentaires

7 Réponses :


7
votes

Jetez un coup d'œil à boost Type Type bibliothèque, en particulier le Function_Traits Fournit une telle fonctionnalité hors de la boîte. Si vous ne pouvez pas utiliser Boost, téléchargez simplement le code et lisez les sources pour un aperçu de la manière dont cela est fait.

Notez que la fonctionnalité est basée sur des types, pas des fonctions concrètes, vous devrez peut-être ajouter du code supplémentaire là-bas.


Après avoir fait de petits tests, cela pourrait ne pas être ce dont vous avez vraiment besoin et si c'est le «code supplémentaire» sera non trivial. Le problème est que le modèle fonction fonctionne sur les signatures de fonction et non les pointeurs de fonction réels, le problème a donc été modifié par "Obtenir le type de retour d'un pointeur de fonction" pour "obtenir la signature d'un pointeur de fonction" qui est probablement la partie la plus difficile là-bas.


7 commentaires

Les types de retour de fonction sont Covariant, un iceberg qui coulera le Titanic.


Hmm oui cela semble regarder. Pour donner un exemple à tout le monde, ça marche comme ceci: Boost :: Function_Traits :: Type> :: résultat_type var1; var1 = 3.14f; Mon seul problème maintenant est comme vous l'avez dit, j'ai besoin du type de la fonction entière afin de passer à ces utilitaires de boost.


@nobugz: Je ne comprends pas vraiment votre commentaire, pouvez-vous expliquer davantage?


Ok - j'ai résolu ce problème maintenant. Modèle Monkey (T) {Boost :: Remove_Pointer :: Résultat_type var1 = ...;; } Singe (foo); Singe (bar); Pas exactement comme ma question initiale posée, mais c'est assez bon pour moi. J'invoque singe au besoin, et mon code est capable d'extraire le type de retour des fonctions et de faire quelque chose dont j'ai besoin.


(Pantalon, ne remarqua pas à quel point le formatage se fait baiser sur des commentaires. Je vais les copier dans une autre réponse.)


@Pauldoo: Je commence à croire qu'il n'est pas possible de faire la dernière étape. Le code d'utilisateur doit fournir les types d'arguments de modèle de classe (lorsque le compilateur peut utiliser la déduction de type pour les modèles de fonctions). En essayant d'ajouter un niveau d'indirection via un modèle de fonction et d'extraire le type du type de retour vous laissera à l'étape 0. Si vous pouvez refroidir le code comme James Hopkin suggère (déplacement du code à l'intérieur d'une fonction modélisée), vous pouvez utiliser le type Déduction là-bas, mais ce type ne peut pas être déplacé à l'extérieur de la fonction en standard C ++.


(N'oubliez pas de upvote James Hopkins Réponse, comme c'est essentiellement ce qu'il a suggéré - pour l'ensemble limité des fonctions NULL-ARY, et JOE GAUTERIN pour la mise en œuvre pratique de ce que James a suggéré)



-1
votes

Essayez quelque chose comme ceci:

template<class T> struct magic_template
{};

template<class T> struct magic_template<T()>
{
    typedef T type;
};


0 commentaires

5
votes

C'est délicat car les noms de fonction sont l'expression pas des types - vous avez besoin de quelque chose comme celui de GCC typeof . Boost's type de est un portable solution qui devient très proche.

Toutefois, si le code peut être organisé de manière à ce que le travail soit effectué dans un modèle de fonction sur lequel foo ou bar peut être transmis, Il y a une réponse directe: xxx


0 commentaires

5
votes

FOO et la barre sont des fonctions, pas des types de fonctions, vous devez donc faire un peu de travail supplémentaire.

Voici une solution utilisant une combinaison de boost :: Function_Traits et boost_typeof. P>

#include <boost/typeof/typeof.hpp>
#include <boost/type_traits.hpp>

float Foo();
int Bar();

int main()
{
  boost::function_traits<BOOST_TYPEOF(Foo)>::result_type f = 5.0f;
  boost::function_traits<BOOST_TYPEOF(Bar)>::result_type i = 1;
  return i;
}
  • Cela fonctionnera pour des fonctions de toute arité jusqu'à 10, ce qui devrait suffire à des utilisations les plus sensibles. Li>
  • Cette utilisation de BOOST_TYPEOF fonctionne sur des plates-formes qui ne fournissent pas de type natif de def., c'est donc raisonnablement portable. Li> ul> p>


0 commentaires

0
votes

Comme suggéré par Dribesas, voici la solution que je suis finalement venu à: XXX

Ce n'est pas exactement le formulaire que je vis avec ma question originale, mais c'est assez proche pour moi.


2 commentaires

Vous avez besoin de supplémentaire's's dedyame in là: typosame boost :: Function_Traits :: Type> :: résultat_type


Vous pouvez perdre le remove_pointer juste en faisant le signature void singe (T *) [Oh oui, vous avez raté le type de retour de singe aussi]




1
votes

Voici le modèle Magic (no Boost est impliqué): xxx

et le compilez via xxx / p>


1 commentaires

Il n'y a pas besoin de ceci en C ++ 11, qui a std :: résultat_of .