Para una clase, quiero almacenar algunos punteros de función para funciones miembro de la misma clase en un objeto de map
almacenamiento std::function
. Pero fallo al principio con este código:
class Foo {
public:
void doSomething() {}
void bindFunction() {
// ERROR
std::function<void(void)> f = &Foo::doSomething;
}
};
Recibo error C2064: term does not evaluate to a function taking 0 arguments
en xxcallobj
combinación con algunos errores de instanciación de plantilla extraños. Actualmente estoy trabajando en Windows 8 con Visual Studio 2010/2011 y en Win 7 con VS10 también falla. El error debe basarse en algunas reglas extrañas de C ++ que no sigo
std::function
, con extrathis
como primer parámetro, comostd::function<void(Foo*, int, int)> = &Foo::doSomethingArgs
O necesitas
para que pueda llamarlo en cualquier instancia, o necesita vincular una instancia específica, por ejemplo
this
fuente
this
?Si necesita almacenar una función miembro sin la instancia de clase, puede hacer algo como esto:
¿Cómo sería el tipo de almacenamiento sin auto ? Algo como esto:
También puede pasar este almacenamiento de funciones a un enlace de función estándar
Notas pasadas y futuras: existía una interfaz anterior std :: mem_func , pero desde entonces ha quedado en desuso. Existe una propuesta, posterior a C ++ 17, para hacer que el puntero a las funciones miembro sea invocable . Esto sería muy bienvenido.
fuente
std::mem_fn
fue eliminado; un montón de sobrecargas innecesarias fueron. Por otro lado, quedó en desuso con C ++ 11 y se eliminará con C ++ 17.std::mem_fun
template<class R, class T> unspecified mem_fn(R T::*);
, y no desaparecerá.Desafortunadamente, C ++ no le permite obtener directamente un objeto invocable que se refiera a un objeto y a una de sus funciones miembro.
&Foo::doSomething
le proporciona un "puntero a la función miembro" que se refiere a la función miembro pero no al objeto asociado.Hay dos formas de evitar esto, una es usar
std::bind
para vincular el "puntero a la función miembro" althis
puntero. La otra es usar una lambda que capture elthis
puntero y llame a la función miembro.Preferiría lo último.
Con g ++ al menos unir una función miembro a esto dará como resultado un objeto de tres punteros de tamaño, y asignar esto a un
std::function
dará como resultado una asignación de memoria dinámica.Por otro lado, una lambda que captura
this
solo tiene un tamaño de puntero, asignarla a unstd::function
no dará como resultado una asignación de memoria dinámica con g ++.Si bien no he verificado esto con otros compiladores, sospecho que se encontrarán resultados similares allí.
fuente
Puede usar functors si desea un control menos genérico y más preciso debajo del capó. Ejemplo con mi win32 api para reenviar el mensaje api de una clase a otra clase.
IListener.h
Oyente.h
Dispatcher.h
Principios de uso
Buena suerte y gracias a todos por compartir conocimientos.
fuente
Puedes evitar
std::bind
hacer esto:fuente