utiliza - programas con ciclo for c++
¿Cómo utilizar el bucle for() basado en rango con std:: map? (5)
Cada elemento del contenedor es un map<K, V>::value_type
, que es un typedef
para std::pair<const K, V>
. En consecuencia, escribirías esto como
for (auto& kv : myMap) {
std::cout << kv.first << " has value " << kv.second << std::endl;
}
Por eficiencia, es una buena idea hacer que el parámetro en el bucle sea una referencia. También puede considerar hacerlo const
si desea una vista de solo lectura de los valores.
El ejemplo común para C ++ 11 basado en rango para () bucles es siempre algo simple como esto:
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };
for ( auto xyz : numbers )
{
std::cout << xyz << std::endl;
}
En cuyo caso xyz
es un int
. Pero, ¿qué pasa cuando tenemos algo como un mapa? ¿Cuál es el tipo de la variable en este ejemplo:
std::map< foo, bar > testing = { /*...blah...*/ };
for ( auto abc : testing )
{
std::cout << abc << std::endl; // ? should this give a foo? a bar?
std::cout << abc->first << std::endl; // ? or is abc an iterator?
}
Cuando el contenedor que se recorre es algo simple, parece que los bucles basados en rango para () nos darán cada elemento, no un iterador. Lo que es bueno ... si fuera iterador, lo primero que siempre tendríamos que hacer es desreferenciarlo de todos modos.
Pero estoy confundido en cuanto a qué esperar cuando se trata de cosas como mapas y multimapas.
(Todavía estoy en g ++ 4.4, mientras que los bucles basados en rangos están en g ++ 4.6+, así que aún no he tenido la oportunidad de probarlo).
De este documento: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2049.pdf
for( type-specifier-seq simple-declarator : expression ) statement
es sintácticamente equivalente a
{
typedef decltype(expression) C;
auto&& rng(expression);
for (auto begin(std::For<C>::begin(rng)), end(std::For<C>::end(rng)); begin != end; ++ begin) {
type-specifier-seq simple-declarator(*begin);
statement
}
}
Entonces, puedes ver claramente que lo que es abc
en tu caso será std::pair<key_type, value_type >
. Así que para imprimir puedes acceder a cada elemento por abc.first
y abc.second
En C ++ 17 esto se denomina enlaces estructurados , lo que permite lo siguiente:
std::map< foo, bar > testing = { /*...blah...*/ };
for ( const auto& [ k, v ] : testing )
{
std::cout << k << "=" << v << "/n";
}
Si el operador de asignación de copia de foo y bar es barato (por ejemplo, int, char, puntero, etc.), puede hacer lo siguiente:
foo f; bar b;
BOOST_FOREACH(boost::tie(f,b),testing)
{
cout << "Foo is " << f << " Bar is " << b;
}
EDIT : El siguiente no funciona como antes :
tiene que ser una declaración , no una expresión de valor l .
foo f;bar b;
for(std::tie(f,b) : testing)
{
cout << "Foo is " << f << " Bar is " << b;
}
Si solo desea ver las claves / valores de su mapa y le gusta usar boost, puede usar los adaptadores boost con los bucles basados en rango:
for (const auto& value : myMap | boost::adaptors::map_values)
{
std::cout << value << std::endl;
}
hay un impulso equivalente :: adapters :: key_values