2009-10-10 6 views
5

Je cherche à simplifier (via make_fn()) la génération d'functors que prétraiter paramètres (via wrap()) pour les fonctions de membres d'arité n.
La génération des foncteurs fonctionne essentiellement, mais jusqu'à présent seulement en spécifiant explicitement les types de paramètres pour la fonction membre.
Maintenant, je voudrais générer le foncteur correct du type de fonction membre il gère:génération de foncteur de type pointeur de fonction membre

struct X {}; 

template<class C, typename T1, bool (C::*F)(T1)> 
inline // there are more for T1..TN 
bool wrap(C* c, X x) 
{ 
    return (c->*F)(process<T1>(x)); 
} 

template<class C, typename T1, bool (C::*F)(T1)> 
inline // there are more for T1..TN 
boost::function<bool (C*, X)> make_fn(F f) // <- problem here, F is not a type 
{ 
    return boost::bind(&wrap<C, T1, F>, _1, _2); 
} 

Avec cela, cependant, vC++ et g ++ ne voyez pas F comme type pour le paramètre de make_fn(). Je dois manquer quelque chose d'évident ici et je me sens un peu aveugle.

L'idée était que cela devrait fonctionner comme ceci:

struct A 
{ 
    bool f1(bool) { return true; } 
}; 

void test() 
{ 
    A a; 
    X x; 
    make_fn(&A::f1)(&a, x); 
} 

Toutes les idées sur la façon de faire ce travail?

Contexte:
J'ai une interface fixe qui, lorsqu'elle est simplifiée, ressemble à ceci:

bool invoke(C* c, const char* const functionName, int argCount, X* args); 

X est un type de variante que je dois convertir certains types de back-end (int, std: :chaîne, ...).
Pour gérer ces appels, j'ai une carte des foncteurs qui sont recherchés par nom et mappez ces appels aux fonctions membres de certaines instances.
L'intention de l'emballage est d'éviter les conversions manuelles et de générer à la place des foncteurs qui effectuent la conversion pour moi ou throw. J'ai ceci fonctionnant avec une solution basée par macro, mais cette solution exige de spécifier les types et le nombre de paramètre explicitement.
Via la résolution de surcharge de fonction j'espère générer le foncteur de conversion correct implicitement de la signature de fonction de membre.

+0

Qu'est-ce que vous essayez vraiment de réaliser? Qu'est-ce que vous voulez simplifier de lier (boost/C++ 0x)? Il semble que ce que vous voulez est un modèle qui prend un seul argument qui est un pointeur de fonction membre et crée un foncteur qui nécessite une instance et le nombre approprié d'arguments sans intervention de l'utilisateur (c'est-à-dire sans que l'utilisateur type explicite, est-ce pas? –

+0

Oui, au fond je veux un foncteur avec un nombre fixe d'arguments qui enveloppe les fonctions membres de arité n et avec des types arbitraires. –

+0

Il me semble que vous voulez déduction de modèle pour un paramètre non type. F est pas un type: il est un pointeur vers une fonction membre particulière, donc vous ne pouvez pas faire 'make_fn (F f)' Je ne sais pas si elle va travailler. il semble que vous voulez construire un modèle d'une variable d'exécution membre-fonction pointeur. – UncleBens

Répondre

3

Il me semble que vous essayez de mettre un pointeur passé à une fonction dans un argument de modèle non de type, que j'ai peur ne va pas travailler (voir les commentaires à votre question).

Ce que vous pouvez faire est de stocker le pointeur de fonction dans un objet fonction. Ce qui suit semble compiler:

#include <boost/bind.hpp> 
#include <boost/function.hpp> 

struct X {}; 

template <class T> 
bool process(X) { return true; } 


template <class C, class T1, class Func> 
struct wrap1 
{ 
    typedef bool result_type; 
    Func f; 

    wrap1(Func f): f(f) {} 

    bool operator()(C* c, X x) 
    { 
     return (c->*f)(process<T1>(x)); 
    } 
}; 

template<class C, typename T1> 
inline // there are more for T1..TN 
boost::function<bool (C*, X)> make_fn(bool (C::*f)(T1)) 
{ 
    return boost::bind(wrap1<C, T1, bool (C::*)(T1)>(f), _1, _2); 
} 


struct A 
{ 
    bool f1(bool) { return true; } 
}; 

void test() 
{ 
    A a; 
    X x; 
    make_fn(&A::f1)(&a, x); 
} 

Cependant, je ne sais pas si cela est une bonne et comment vous devez créer le reste des emballages. Pour ce dernier, vous pourriez juste obtenir un compilateur qui supporte des modèles variés. :)

+0

Althoug h j'avais espéré éviter de générer un autre foncteur, cela fonctionne - merci :) Pour les modèles pseudo-variadiques (j'en ai besoin dans vc8) make_fn() peut être défini pour toutes les arités nécessaires. –

Questions connexes