autopeut améliorer les performances en évitant les conversions implicites silencieuses . Un exemple que je trouve convaincant est le suivant.
std::map<Key, Val> m;
// ...
for (std::pair<Key, Val> const& item : m) {
// do stuff
}
Vous voyez le bug? Nous voici, pensant que nous prenons élégamment chaque élément de la carte par référence const et utilisons la nouvelle expression range-for pour clarifier notre intention, mais en réalité nous copions chaque élément. En effet , std::map<Key, Val>::value_typeest std::pair<const Key, Val>, non std::pair<Key, Val>. Ainsi, lorsque nous avons (implicitement):
std::pair<Key, Val> const& item = *iter;
Au lieu de prendre une référence à un objet existant et de le laisser là, nous devons faire une conversion de type. Vous êtes autorisé à prendre une référence const à un objet (ou temporaire) d'un type différent tant qu'une conversion implicite est disponible, par exemple:
int const& i = 2.0; // perfectly OK
La conversion de type est une conversion implicite autorisée pour la même raison que vous pouvez convertir un const Keyen un Key, mais nous devons construire un temporaire du nouveau type afin de permettre cela. Ainsi, effectivement, notre boucle:
std::pair<Key, Val> __tmp = *iter; // construct a temporary of the correct type
std::pair<Key, Val> const& item = __tmp; // then, take a reference to it
(Bien sûr, il n'y a pas réellement d' __tmpobjet, il est juste là pour l'illustration, en réalité le temporaire sans nom est juste lié à itemsa durée de vie).
Je change simplement en:
for (auto const& item : m) {
// do stuff
}
vient de nous sauver une tonne de copies - maintenant le type référencé correspond au type d'initialisation, donc aucun temporaire ou conversion n'est nécessaire, nous pouvons simplement faire une référence directe.