Pregunta

Considere una clase de plantilla como:

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

Esto puede ser instanciado utilizando:

Proxy<int, &fn1> p1;

Pero declarar explícitamente el tipo de valor de retorno parece innecesario. Lo que estoy tratando de lograr es algo como:

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

Por desgracia, no soy un C ++ esperar y esto parece un rincón escondido de la lengua (al menos para mí).

Si tan sólo pudiera llegar desde el puntero a la función de su tipo - algo así como:      std :: TR1 :: result_of :: tipo 1 // Error de error C2923: 'std :: TR1 :: result_of': 'na1' no es un argumento de tipo de plantilla válido para el parámetro '_Fty'

el error tiene sentido ya que el parámetro no es un "tipo" en absoluto

C ++ 0x tiene la decltype (y FN1), pero que está a años de distancia.

Cualquier forma de hacer esto en C ++ 03 (+ TR1)?

Restricciones:  -. No quiero pasar el funtor, F1 y F2 que permanecer funciones globales que tienen un valor de retorno (no puede moverlo a parámetros))

¿Fue útil?

Solución

Esto no es posible en C ++ 03. Si desea pasar un puntero a función como un parámetro no el tipo, el compilador tiene que conocer el tipo de parámetro. Así que hay que proporcionar las piezas que faltan (en este caso, el tipo de retorno). Se puede dar el proxy del puntero de función como un valor en tiempo de ejecución, y dotarla con el tipo de la misma como el único argumento. Posteriormente, se podría escribir una función de generador para usted que hace este trabajo:

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

Por desgracia, en la corriente de C ++, que todavía tiene que darle el tipo con el fin de asignar a una variable automática:

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

No se puede utilizar auto p = make_proxy(&fn1); todavía. Tenga en cuenta que si desea utilizar un tipo de función en el lado izquierdo, usted tiene que cambiar la función de generador para proporcionar no un tipo de puntero de función:

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

Ahora usted puede hacer

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

usando el proxy, ahora se puede simplemente hacer

doSomething(make_proxy(&fn1));

Y si es doSomething de plantilla o de otra forma polimórfica, no se le requiere conocer el tipo exacto de la función.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top