Utilice siempre la variante que describe mejor lo que pretende hacer. Es decir
Para cada elemento x
en vec
, hacer bar.process(x)
.
Ahora, examinemos los ejemplos:
std::for_each(vec.begin(), vec.end(),
std::bind1st(std::mem_fun_ref(&Bar::process), bar));
También tenemos una for_each
, sí, sí . Tenemos el [begin; end)
rango en el que queremos operar.
En principio, el algoritmo era mucho más explícito y, por lo tanto, preferible a cualquier implementación escrita a mano. Pero entonces ... Binders? Memfun? Básicamente C ++ interna de cómo obtener una función miembro? ¡Para mi tarea, no me importan ! Tampoco quiero sufrir esta sintaxis verbosa y espeluznante.
Ahora la otra posibilidad:
for (std::vector<Foo>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
bar.process(*it);
}
Por supuesto, este es un patrón común para reconocer, pero ... creando iteradores, bucles, incrementos, desreferenciación. Estas también son cosas que no me importan para poder hacer mi tarea.
Es cierto que se ve mucho mejor que la primera solución (al menos, el cuerpo del bucle es flexible y bastante explícito), pero aún así, no es realmente tan bueno. Usaremos este si no tuviéramos una mejor posibilidad, pero tal vez tengamos ...
¿Una mejor manera?
Ahora de vuelta a for_each
. ¿No sería genial decir literalmente for_each
y ser flexible en la operación que también se debe hacer? Afortunadamente, desde C ++ 0x lambdas, somos
for_each(v.begin(), v.end(), [&](const Foo& x) { bar.process(x); })
Ahora que hemos encontrado una solución abstracta y genérica para muchas situaciones relacionadas, vale la pena señalar que en este caso particular, hay un favorito absoluto # 1 :
foreach(const Foo& x, vec) bar.process(x);
Realmente no puede ser mucho más claro que eso. Afortunadamente, C ++ 0x get tiene una sintaxis similar incorporada .
map(bar.process, vec)
aunque se desaconseja el mapa de efectos secundarios y se recomiendan las comprensiones de lista / expresiones generadoras sobre el mapa).