2009-10-10 29 views
5

Estoy tratando de simplificar (a través de make_fn()) la generación de funtores que preproceso parámetros (a través de wrap()) para funciones miembro de aridad n .
La generación de los funtores está básicamente funcionando, pero hasta ahora solo especificando explícitamente los tipos de parámetros para la función de miembro.
Ahora me gustaría para generar el funtor correcta del tipo de función miembro que maneja:generación funtor de la función miembro de tipo puntero

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); 
} 

Con esto, sin embargo, VC++ y g ++ no ven F como un tipo para el parámetro de make_fn(). Debo perderme algo obvio aquí y me siento algo ciego.

La idea era que debería funcionar así:

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

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

Cualquier ideas sobre cómo hacer que el trabajo?

Antecedentes:
I tiene una interfaz fija que, cuando simplificada, se ve así:

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

X es un tipo de variante, que tengo que convertir a ciertos tipos de backend (int, std: :cuerda, ...).
Para manejar estas llamadas tengo un mapa de funtores que se buscan por nombre y asignar estas llamadas a funciones miembro de alguna instancia.
La intención del ajuste es evitar las conversiones manuales y en su lugar generar funtores que hacen la conversión para mí o throw. Tengo esto trabajando con una solución basada en macro, pero esa solución requiere especificar los tipos y el conteo de parámetros explícitamente.
A través de la resolución de sobrecarga de la función espero generar el functor de conversión correcto implícitamente desde la firma de la función miembro.

+0

¿Qué es lo que realmente estás tratando de lograr? ¿Qué es lo que quieres simplificar de bind (boost/C++ 0x)? Parece que lo que desea es una plantilla que tome un solo argumento que sea un puntero de función miembro y cree un functor que requiera una instancia y el número apropiado de argumentos sin la intervención del usuario (es decir, sin que el usuario haga el número de argumento/Escriba explícito, ¿es así? –

+0

Sí, básicamente quiero un funtor con un número fijo de argumentos que envuelva las funciones miembro de arity n y con tipos arbitrarios. –

+0

Me parece que desea la deducción de plantilla para un parámetro que no sea de tipo. F no es un tipo: es un puntero a una función de miembro en particular, por lo tanto no se puede hacer 'make_fn (F f)'. No estoy seguro de si va a funcionar: parece que quieres construir una plantilla de una variable miembro-función-puntero de tiempo de ejecución – UncleBens

Respuesta

3

Me parece que está intentando convertir un puntero pasado a una función en un argumento de plantilla sin tipo, lo que me temo que no va a funcionar (ver comentarios a su pregunta).

Lo que podría hacer es almacenar el puntero de función en un objeto de función. A continuación aparece para compilar:

#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); 
} 

Sin embargo, no estoy seguro si eso es bueno y cómo debe crear el resto de los envoltorios. Para este último, puede obtener un compilador que admita plantillas variadas. :)

+0

Althoug h esperaba evitar generar otro functor, esto está funcionando - gracias :) Para las plantillas pseudo-variadas (lo necesito en vc8) make_fn() se puede definir para todas las aries necesarias. –

Cuestiones relacionadas