¿C++ 11 proporciona delegados?Delegado en C++ 11
Si no es así, ¿cuál es la mejor (más eficiente) forma de hacer algo similar en C++? Boost.Signals? FastDelegate? ¿Algo más?
¿C++ 11 proporciona delegados?Delegado en C++ 11
Si no es así, ¿cuál es la mejor (más eficiente) forma de hacer algo similar en C++? Boost.Signals? FastDelegate? ¿Algo más?
Usted puede obtener la semántica delegado como el uso de bind
para unirse a una función miembro de una instancia de clase:
#include <functional>
struct C
{
void Foo(int) { }
};
void Bar(std::function<void(int)> func)
{
func(42); // calls obj.Foo(42)
}
int main()
{
using namespace std::placeholders;
C obj;
Bar(std::bind(&C::Foo, obj, _1));
}
En este ejemplo, Bar()
toma cualquier cosa que tenga un solo int
parámetros y que devuelve void
.
En main()
, vinculamos un puntero a la función de miembro C::Foo
a la instancia de C
con el nombre obj
. Esto nos da un objeto que se puede llamar con un solo parámetro int
y que devuelve void
.
Llamamos Bar()
con este objeto y Bar()
hace la llamada obj.Foo(42)
.
+1, o simplemente puedes convertir C en un funtor. –
@jk: solo algunas veces Obviamente en este caso podrías, pero no tengo muchas clases en mi aplicación que tengan solo una función miembro :-) –
El mecanismo C siempre ha sido puntero a la función & bastón (excepto qsort() y bsearch() que no tomó un bastón).
Así que uno siempre pasaría el objeto de clase como testigo.
ej .:
class tp {
public:
tp() { n = 0; }
void m(int z) { printf("%d is %d\n", n++, z++); }
int n;
};
void higher_func(int *opx, int cnt, void *handler(int itm, void *baton), void *baton)
{
for (int i = 0; i < cnt; i++)
handler(opx[itm], baton);
}
/* You would need to provide this stub -- potentially templateable */
void translate_baton(int itm, void *baton) { ((tp *)baton)->m(itm); }
/* used like so: */
int main()
{
int array[7];
//...
tp cx;
higher_func(array, 7, translate_baton, &cx);
}
Esta pregunta no es sobre C: el mecanismo C está disponible en C++ pero eso no lo hace la mejor opción. –
Trabajo mucho con los delegados en .NET y créanme de esta manera me habría ahorrado problemas en el camino de los delegados que al revés. – Joshua
No necesariamente tienen que esperar para C++ 0x. Puede implementar Delegados casi tan bien en el estándar actual C++ 03. Simplemente tiene que sobrecargar el operador(), de modo que puede llamar al MyObjectFunctor functor; functor();
y dado que el funtor es un objeto, puede pasarlo como un delegado/objeto a funciones;
La versión actual de la STL define el encabezado <algorithm>
que proporciona funciones listas para ser utilizadas con Functors/Lambdas/Delegates.
ejemplo simple de un functor.
struct FunctorDelegate
{
// as so to delegate as a function that takes an int input
void operator()(int)
{
// do what I want
}
};
int main()
{
//... do some stuffs with an std::vector<int> aRange;
FunctorDelegate functor;
std::for_each(aRange.begin(), arange.end(), functor);
}
Lo que los delegados pueden hacer es la capacidad de almacenar, por ejemplo, 'int A :: func1 (int, int)' o 'int B :: func2 (int, int)' en una variable (digamos 'f'), entonces que podría llamarse como 'int v = f (a, 12, 34);' o 'int v2 = f (b, 42, 24);'. En su ejemplo, se podría llamar al funtor, pero no se puede tratar como una abstracción de la función tipo 'void (int)'. –
No necesita C++ 0x. en <functional>
tiene bind1st
bind2nd
mem_fun
y mem_fun_ref
. También tiene Boost.Bind que generaliza todas las funciones anteriores (IIRC).
Yendo de la memoria ...
vector<Foo> foo = makeVector();
vector<Foo*> foop = makeVectorP();
vector<Bar> bar1,bar2,bar3,bar4;
transform(foo.begin(), foo.end(), back_inserter(bar1), mem_fun_ref(&Foo::getBar));
transform(foop.begin(), foop.end(), back_inserter(bar2), mem_fun(&Foo::getBar));
transform(foo.begin(), foo.end(), back_inserter(bar3), bind1st(&bar_from_foo));
transform(foo.begin(), foo.end(), back_inserter(bar4), boost::bind(&bar_from_foo, _1));
bind1st, bind2nd, mem_fun y mem_fun_ref están en desuso en C++ 11. –
Aunque std::function
funciona muy bien, me gustaría señalar esta bonita pieza de código delegado, por escrito here (incluyendo ejemplo de uso!). A continuación de las referencias y respuestas, puede leer todo sobre cómo se construye esta clase Delegate
y por qué puede ser más rápido que std::function
.
Tenga en cuenta también que mi pregunta here para un problema que me encontré con él en VS 2015.
Cuál es incorrecto con los punteros de función? – alternative
No puedo usarlo con el método de clase:/ – dot222
sí, puedes http: //www.parashift.com/C++ - faq-lite/punteros-a-miembros.html pero probablemente hay cosas mejores para usar, p. Las funciones de C++ no necesitan ser métodos, o puedes convertir la clase en un functor –