c++ auto - Comment utiliser la boucle for for()avec std::map?




vector (5)

L'exemple courant pour les boucles for () de C ++ 11 est toujours quelque chose de simple comme ceci:

std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };
for ( auto xyz : numbers )
{
     std::cout << xyz << std::endl;
}

Dans ce cas, xyz est un int . Mais, que se passe-t-il quand nous avons quelque chose comme une carte? Quel est le type de la variable dans cet exemple:

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?
}

Lorsque le conteneur traversé est quelque chose de simple, il semblerait que les boucles for () basées sur la distance nous donneront chaque élément, pas un itérateur. Ce qui est bien ... si c'était itérateur, la première chose que nous aurions toujours à faire est de le déréférencer de toute façon.

Mais je suis confus quant à savoir à quoi s'attendre quand il s'agit de choses comme des cartes et des multimaps.

(Je suis toujours sur g ++ 4.4, alors que les boucles basées sur une gamme sont en g ++ 4.6+, donc je n'ai pas encore eu l'occasion de l'essayer.)


Answers

En C ++ 17, cela s'appelle des liaisons structurées , ce qui permet ce qui suit:

std::map< foo, bar > testing = { /*...blah...*/ };
for ( const auto& [ k, v ] : testing )
{
  std::cout << k << "=" << v << "\n";
}


Chaque élément du conteneur est une map<K, V>::value_type , qui est un typedef pour std::pair<const K, V> . Par conséquent, vous écririez ceci comme

for (auto& kv : myMap) {
    std::cout << kv.first << " has value " << kv.second << std::endl;
}

Pour l'efficacité, c'est une bonne idée de faire du paramètre dans la boucle une référence. Vous pouvez également envisager de le faire const si vous voulez une vue en lecture seule des valeurs.


Si l'opérateur d'attribution de copie de foo et de la barre est bon marché (par exemple, int, char, pointeur, etc), vous pouvez faire ce qui suit:

foo f; bar b;
BOOST_FOREACH(boost::tie(f,b),testing)
{
  cout << "Foo is " << f << " Bar is " << b;
}

EDIT : Le ci-dessous ne fonctionne pas comme avant :, il doit être une déclaration , pas une expression lvalue .

foo f;bar b;
for(std::tie(f,b) : testing)
{
   cout << "Foo is " << f << " Bar is " << b;
}

Il existe une méthode pour parcourir uniquement les propriétés propres à un objet, sans inclure celles du prototype:

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // do something
}

mais il sera toujours itérer sur les propriétés personnalisées.

En javascript, toute propriété personnalisée peut être affectée à un objet, y compris un tableau.

Si on veut itérer sur un tableau éparpillé, for (var i = 0; i < array.length; i++) if (i in array)ou array.forEachavec es5shimdevrait être utilisé.





c++ c++11 for-loop dictionary