2012-03-02 39 views
7

Imagínese que tengo la siguiente función libre y funtor:Funciones/funtores como parámetros de plantilla. Pueden ser almacenados?

void myFreeFunction(void) 
{ 
    cout << "Executing free function" << endl; 
} 

struct MyFunctor 
{ 
    void operator()(void) 
    { 
     cout << "Executing functor" << endl; 
    } 
}; 

según lo descrito por this answer, puedo pasar mi función o funtor como un argumento de plantilla a otra función:

template <typename F> 
void doOperation(F f) 
{ 
    f(); 
} 

y luego llamar a:

doOperation(myFreeFunction); 
doOperation(MyFunctor()); 

Hasta ahora todo bien. Pero lo que si quiero algo como lo siguiente:

template<typename Callback> 
class MyClass 
{ 
private: 
    Callback mCallback; 

public: 
    MyClass(){} 

    void execute() 
    { 
     mCallback(); 
    } 
}; 

En este caso estoy especificando la función/funtor cuando declaro la clase pero no llamándolo hasta más tarde. Funciona para funtores:

MyClass<MyFunctor> myClass1; 
myClass1.execute(); 

Pero no por funciones:

MyClass<myFreeFunction> myClass2; 
myClass2.execute(); 

compilador dice: C2923

error: 'MiClase': 'myFreeFunction' no es un argumento de tipo de plantilla válido para el parámetro 'Devolución de llamada'

Que es justo ... pero ¿cómo lo harías? estructura esto?

Nota: Conozco std :: function y puedo terminar usando esto. Sin embargo, es mucho más lento, así que estoy buscando todas las opciones.

Gracias,

David

+0

usando boost :: bind() y boost :: function(), puede lograr lo que está buscando. Si está interesado, puedo dar un ejemplo. – Lou

+0

Gracias, pero como señalé al final, ya conozco la función std :: como solución. Sin embargo, parece tener una sobrecarga de rendimiento como resultado de que la función no está en línea. – PolyVox

Respuesta

7

El problema es que freefunction no es un tipo sino un elemento de una de (int este caso un puntero de función.

para solucionar este problema que necesita para aprobar la función de, en la construcción, sin embargo, todavía necesita saber el tipo exacto

myclass<call_back_t> my_class(call_back); 

EDIT:. en C++ 11 del tipo se puede conseguir a partir decltype(call_back)

sin embargo recibir la llamada de vuelta puede ser un problema a menudo es mucho más fácil de crear una función de generador de

//this should be in the namespace of the class or a static member of it 
template<FuncType> 
myclass<FuncType> make_class(FuncType func) 
{ 
    return myclass<FuncType>(func); 
} 
//called like 
myclass mc=make_class(&my_callback); 

No para llegar a alterar el constructor

template<typename CallBack> 
myclass{ 
private: 
    CallBack call_back; 
public: 
    myclass(CallBack call_back_) 
    : call_back(call_back_) 
    {} 
}; 

o algo por el estilo

+0

Excelente, gracias por la información.He ajustado MyClass como sugirió y ahora puedo hacerlo: – PolyVox

+0

Meh, parece que no puedo agregar más preguntas en los comentarios. Básicamente, su solución funciona tanto para funtores como para funciones, así que gracias por eso. Hay un pequeño problema sintáctico que tengo con los funtores, pero haré una nueva pregunta si no puedo resolverlo. – PolyVox

+0

@PolyVox Simplemente edite su publicación o publíquela aquí intentaré y ayudaré – 111111

Cuestiones relacionadas