Ellos no son los mismos en todos. std::function
es un tipo complejo, pesado, con estado, casi mágico que puede contener cualquier tipo de entidad invocable, mientras que un puntero a la función es solo un simple puntero. Si usted puede salirse con la suya, se debe preferir cualquiera de los punteros de función desnudas o auto
- tipos bind
/auto
-lambda. Solo use std::function
si realmente necesita una forma sistemática de organizar una colección heterogénea de entidades invocables, como funciones, funtores, captura de lambdas y expresiones de enlace.
Actualizar: un poco de explicación sobre auto
tipos: Comparación de las dos funciones siguientes:
void do_something_1(std::function<void(int)> f, int a) { f(a); }
template <typename F, typename A> void do_something_2(F f, A a) { f(a); }
Ahora imagine la invocación de ellos con una lambda o una expresión bind
:
do_something_X([foo, &bar](int n){ bar += n*foo; }, 12);
do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
La segunda versión con la plantilla es más eficiente, porque en ambos casos, el argumento F
se deduce al tipo real e incognoscible de la expresión. La primera versión, con std::function
, no es una plantilla y puede parecer más simple y deliberada, pero siempre fuerza la construcción del objeto std::function
, y muy posiblemente conlleva varios borrados de tipo y costos de despacho virtual.
¿qué es _1 aquí? – makar
@makar Es el identificador utilizado por 'std :: bind' para referirse al primer argumento de la función resultante. Es un poco como: 'void bound (int _1) {func (_1, 5); } ' –
[El enlace aquí] (http://stackoverflow.com/questions/25848690/should-i-use-stdfunction-or-a-function-pointer-in-c) menciona otro diferente entre el puntero de función y la función std :: : La captura lambda no se puede utilizar en el puntero de función. Así que si intenta usar lambda '[&] (int a, int b) {/ * blah * /}', o '[=] (int a, int b) {/ * blah * /} ', tendrá un error de compilación. El único formato válido es '[] (int a, int b) {/ * blah * /}' – r0ng