Comment puis-je obtenir un const_iterator en utilisant auto?

Première question: est-il possible de “forcer” un const_iterator utilisant auto? Par exemple:

 map usa; //...init usa auto city_it = usa.find("New York"); 

Je veux juste interroger, au lieu de changer tout ce qui est indiqué par city_it , je voudrais donc que city_it soit map::const_iterator . Mais en utilisant auto, city_it est identique au type de retour de map::find() , qui est map::iterator . Toute suggestion?

Désolé, mais je pense que la meilleure suggestion est de ne pas utiliser d’ auto , car vous voulez effectuer une conversion de type (implicitement valide). auto est destiné à déduire le type exact , ce qui n’est pas ce que vous voulez ici.

Il suffit de l’écrire de cette façon:

 std::map::const_iterator city_it = usa.find("New York"); 

Comme indiqué correctement par MooingDuck, l’utilisation d’alias de type peut améliorer la lisibilité et la maintenabilité de votre code:

 typedef std::map my_map; my_map::const_iterator city_it = usa.find("New York"); 

Il ne s’agit pas là d’une parsing radicalement différente de la conversion en const par rapport à la réponse de @ Jollymorphic, mais je pense qu’il est pratique d’avoir une fonction simple comme celle-ci:

 template T const& constant(T& v){ return v; } 

Ce qui rend la conversion beaucoup plus attrayante pour les yeux:

 auto it = constant(usa).find("New York"); // other solutions for direct lengths comparision std::map::const_iterator city_it = usa.find("New York"); auto city_it = const_cast&>(usa).find("New York"); 

Eh bien, je dirais que plus grand n’est pas toujours mieux. Vous pouvez bien sûr choisir le nom de la fonction en fonction de vos préférences – as_const ou juste const_ sont des alternatives possibles.

Une autre variante utilisant auto (en gardant à la fois un usable mutable et un usa const):

 map usa; //...init usa const auto &const_usa = usa; auto city_it = const_usa.find("New York"); 

Si vous n’avez pas besoin que la carte soit mutable après init, il y a d’autres options.

vous pouvez définir usa comme const et l’initialiser avec un appel de fonction:

 const map usa = init_usa(); auto city_it = usa.find("New York"); 

ou en utilisant un lambda pour initier une carte const:

 const auto usa = [&]()->const map { map usa; //...init usa return usa; }(); auto city_it = usa.find("New York"); 

Une solution propre consiste à utiliser une référence constante à la carte par ailleurs modifiable:

 const auto &const_usa = usa; auto city_it = const_usa.find("New York"); 

Cela vous assurera de ne pas pouvoir modifier const_usa et utilisera des iterators const.

Depuis C ++ 17, vous pouvez utiliser std::as_const comme ceci:

 #include  // ... auto city_it = std::as_const(usa).find("New York"); 

Je ne suis pas en mesure de tester ça maintenant, mais je pense que ça va faire l’affaire:

 auto city_it = const_cast< const map & >(usa).find("New York"); 

Vous pouvez utiliser auto pour “suivre” un type ou “déduire” un type: // deduce auto city_it = usa.find("New York");

// track auto city_it = std::map::const_iterator( usa.find("New York"));

En outre, regarder est le style moderne de C ++ par Herb Sutter, qui couvre la plupart de ces conseils de déductions de type. https://youtu.be/xnqTKD8uD64