Uso estándar preferido: gama basada para o std:: para cada
En C++11, hay dos bucles sobre todos los elementos (rango basado en for y for_each). ¿Hay alguna razón para preferir uno sobre el otro o hay situaciones en las que uno encaja mejor?
for (auto& elem: container) {
// do something with elem
}
std::for_each(container.begin(), container.end(),
[](Elem& elem) {
// do something with elem
});
Mi idea sería que el primero es más simple y es similar a los bucles basados en rango en otros lenguajes, mientras que el segundo también funciona para secuencias que no son contenedores completos y el segundo es más similar a otros std
-algoritmos.
2 answers
-
for
basado en rangos es obviamente más fácil de leer y escribir. Está especializado para esta tarea.EDIT: Puede romper un rango-for sin abusar de una excepción. (Aunque
std::find_if
sustituido porstd::for_each
permite esto también.) -
std::for_each
, irónicamente, es la alternativa que en realidad está basada en rango y le permite seleccionar valoresbegin
yend
particulares en lugar de todo el contenedor. (EDITAR: Esto puede ser hackeado usando una clase simplerange
que proporcionabegin
yend
miembros, como los proporcionados por Boost.)También
for_each
puede ser más elegante cuando se usan funciones de orden superior: se puede usar como argumento parabind
, y el tercer argumento ya es un funtor.
Principalmente es una cuestión de estilo. Sin embargo, la mayoría de los lectores probablemente prefieren ver for ( auto &a : b )
, y la mayoría de las implementaciones ahora lo soportan.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-04 01:19:03
std::for_each
devuelve el funtor que se ha utilizado internamente en el bucle, por lo que proporciona un mecanismo limpio para recopilar información sobre los elementos de la secuencia. El bucle for basado en rango es solo un bucle, por lo que cualquier estado que se use fuera del bucle debe declararse fuera de ese ámbito. En su ejemplo, si el propósito de los bucles es mutar cada elemento de la secuencia, entonces no hay mucha diferencia en absoluto. Pero si no está utilizando el valor devuelto de la for_each
entonces probablemente estés mejor con el bucle simple. Por cierto, el bucle basado en rango también funciona en matrices de estilo C y std:: strings.
Este es un ejemplo de usar el valor de retorno de for_each
, aunque no es muy imaginativo o útil. Es solo para ilustrar la idea.
#include <iostream>
#include <array>
#include <algorithm>
struct Foo {
void operator()(int i) { if (i > 4) sum += i;}
int sum{0};
};
int main() {
std::array<int, 10> a{1,2,3,4,5,6,7,8,9,10};
Foo foo = std::for_each(a.begin(), a.end(), Foo());
std::cout << "Sum " << foo.sum << "\n";
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-03 14:05:40