13 votes

Qu'est-ce qu'une "boucle à base de rangs laconiques" ?

Clang a commencé à mettre en œuvre boucles for basées sur des rangs laconiques de n3994 . Souvent, lors de l'introduction de boucles for basées sur le rang, nous voyons du code sous la forme de for (auto & v : vector) pour éviter les copies inutiles. Il semble que n3994 propose que for (auto && v : vector) est supérieur à tout point de vue. J'ai quelques questions à poser :

  1. Quels sont les avantages de cette dernière forme par rapport à la première ? Pourquoi opte-t-on généralement pour auto & au lieu de auto && si cette dernière est clairement avantageuse ?
  2. Le fait d'utiliser la nouvelle boucle basée sur les rangs équivaut-il à auto && va-t-elle rompre le code existant ? Aura-t-il un impact réel sur le nouveau code ?
  3. Cela ne risque-t-il pas d'attirer l'attention des débutants sur le fait que leur code est en fait équivalent à auto && ?

7voto

T.C. Points 22510

Quels sont les avantages de cette dernière forme par rapport à la première ? Pourquoi opte-t-on généralement pour auto & au lieu de auto && i est clairement avantageuse ?

auto & ne fonctionne pas si le déréférencement de l'itérateur renvoie des objets proxy plutôt que des références réelles, car vous tenteriez de lier une référence lvalue non-const à une référence temporaire. L'exemple standard est l'abomination connue sous le nom de std::vector<bool> ; le déréférencement de son itérateur renvoie un objet proxy de type std::vector<bool>::reference qui représente un seul bit dans le vecteur. Étant donné que la plupart des itérateurs renvoient des références réelles, ce problème ne se pose pas souvent.

Est-ce que le fait de rendre la nouvelle boucle basée sur le rang-for équivalente à auto && va casser le code existant ? Cela aura-t-il un impact réel sur le nouveau code ?

Non, parce que la nouvelle syntaxe, for(elem : range) ne sera pas compilé dans le code existant.

Cela ne risque-t-il pas d'attirer l'attention des débutants sur le fait que leur code est en fait équivalent à auto && ?

Pourquoi serait-ce un piège ? auto && a l'avantage de fonctionner pour tout. On pourrait dire que le fait de ne pas avoir à enseigner aux débutants tous les détails de la déduction de type, de l'effondrement des références, etc. est en fait un avantage, car cela rend le langage plus facile à apprendre.

7voto

Praetorian Points 47122

Quels sont les avantages de cette dernière forme par rapport à la première ?

Dans le formulaire for(auto& v : vector) le type de v est déduit comme une référence lvalue au type obtenu en déréférençant le type d'itérateur du conteneur. Cela signifie que si le résultat du déréférencement de l'itérateur est une valeur r (pensez à std::vector<bool> qui renvoie un type de proxy représentant une référence à un seul bool ), le code ne pourra pas être compilé, car une référence lvalue ne peut pas se lier à une rvalue.

Lorsque vous écrivez for(auto&& v : vector) Il s'agit d'un référence universelle , c'est-à-dire le type de v sera déduit comme une référence rvalue dans le cas décrit ci-dessus, ou comme une référence lvalue dans le cas habituel où le déréférencement de l'itérateur renvoie une référence à l'élément du conteneur. Cela fonctionne donc dans le cas vector<bool> également. C'est pourquoi cette forme doit être privilégiée si vous envisagez de modifier les éléments sur lesquels vous itérez à l'intérieur de la boucle.

Pourquoi choisissons-nous généralement auto& au lieu de auto&& si cette dernière est clairement avantageuse ?

Vous ne devriez pas. Le seul inconvénient auquel je peux penser auto&& est qu'il ne garantit pas que les modifications que vous apportez aux éléments se propagent nécessairement au conteneur, mais c'est le signe d'une conception défectueuse, et je ne pense pas qu'il vaille la peine de s'en prémunir.

Le fait d'utiliser la nouvelle boucle basée sur les rangs équivaut-il à auto && va-t-elle casser le code existant ?

Je ne vois pas comment cela peut casser le code existant parce que l'ancienne syntaxe continuera à fonctionner comme elle le fait aujourd'hui. Mais si vous voulez dire remplacer le code existant par la nouvelle syntaxe, alors cela pourrait avoir un effet si le code que vous remplacez est la syntaxe auto const& forme. Voir aussi cet exemple . Remarquez comment le auto const& appelle la version const tandis que les deux autres appellent la fonction non const version ? Le remplacement de la première version par la version laconique modifiera la fonction membre appelée.

Cela aura-t-il un impact réel sur le nouveau code ?

Encore une fois, ce n'est pas différent d'un ancien code qui utilise auto&& Aujourd'hui, il n'y a donc pas de différence. Si vous l'utilisez à des endroits où vous n'avez pas l'intention de modifier les éléments, le compilateur ne vous empêchera plus de le faire accidentellement, et vous pourrez appeler une surcharge différente, comme le montre l'exemple ci-dessus.

Cela ne risque-t-il pas d'attirer l'attention des débutants sur le fait que leur code est en fait équivalent à auto && ?

Je ne suis pas sûr de comprendre ce que vous voulez dire, mais si vous demandez si les débutants écriront du code sans connaître ou comprendre les subtilités de l'effondrement des références, alors oui, il est possible qu'ils le fassent. Mais c'est l'un des objectifs déclarés de l'article que vous avez cité en lien. L'argument est que vous pouvez éviter d'enseigner ces concepts difficiles dès le départ, mais présenter aux débutants une syntaxe unique pour les systèmes basés sur l'intervalle for des boucles qui fonctionnent avec tout. En ce qui concerne ce point, je pense que la syntaxe a du mérite, mais si l'on considère les choses d'un point de vue const correct, je le désapprouve parce que je préfère utiliser des auto const& si je veux un accès en lecture seule aux éléments, et alors la syntaxe laconique semble asymétrique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X