45 votes

N'est-ce pas const auto & redondant?

J'ai trouvé ce code dans l'un des livres de Stroustrup:

 void print_book(const vector<Entry>& book)
{
     for (const auto& x : book) // for "auto" see §1.5
           cout << x << '\n';
}
 

Mais les const semblent redondants car x sera déduit comme étant un const_iterator puisque book est const dans le paramètre. Est-ce que const auto vraiment mieux?

70voto

Nawaz Points 148870

À mon avis, cela semble explicite, c'est pourquoi c'est mieux . Donc, si je veux dire const , alors je préférerais l'écrire explicitement. Il améliore le raisonnement local et aide ainsi les autres à comprendre le code relativement facilement - les autres programmeurs n'ont pas à regarder la déclaration de book et en déduire que x est const ainsi que.

34voto

Hurkyl Points 1718

Le code ne doit pas uniquement être lu par le compilateur - il est également accessible aux humains. La concision n’est bonne que si elle ne se fait pas au détriment de la lisibilité.

Dans le code donné, la déduction de la constance est immédiate. Avec votre modification proposée, pour déduire la constance, il faudrait que le lecteur se souvienne avec précision ou revoie la définition de book .

Si le lecteur est censé être conscient de la constance, la brièveté serait ici contre-productive.

14voto

Andreas DM Points 4427

C'est beaucoup plus clair en voyant le mot-clé const. Vous reconnaîtrez immédiatement que ça ne va pas être modifié, si l' const mot-clé n'était pas là, nous ne savons pas, sauf si nous avons regardé jusqu'à la signature de la fonction.

À l'aide de l' const mot-clé explicitement est beaucoup mieux pour les lecteurs de code.


En outre, lorsque vous lisez le code ci-dessous vous vous attendez à ce qu' x est modifiable

for (auto& x : book) { ... }

Et puis, quand vous essayez de modifier x vous trouverez qu'il provoque une erreur, car book est const.
Ce n'est pas un code clair, à mon avis. Il est préférable de préciser dans le code x est pas va être modifié, de sorte que d'autres personnes qui lisent le code de leurs attentes droite.

7voto

Jordan Melo Points 483

Je vais prendre un angle différent ici. const et const_iterator moyenne de choses complètement différentes.

const appliqué à un itérateur qui signifie que vous ne pouvez pas modifier l'itérateur lui-même, mais vous pouvez modifier l'élément de points, un peu comme un pointeur déclaré comme int* const. const_iterator signifie que vous ne pouvez pas modifier l'élément de points, mais vous pouvez toujours modifier l'itérateur lui-même (ie. vous pouvez incrémenter et décrémenter) un peu comme un pointeur déclaré comme const int*.

std::vector<int> container = {1, 2, 3, 4, 5};
const std::vector<int> const_container = {6, 7, 8, 9, 0};
auto it1 = container.begin();
const auto it2 = container.begin();
auto it3 = const_container.begin();
const auto it4 = const_container.begin();

*it1 = 10; //legal
*it2 = 11; //legal
*it3 = 12; //illegal, won't compile
*it4 = 13; //illegal, won't compile

it1++; //legal
it2++; //illegal, won't compile
it3++; //legal
it4++; //illegal, won't compile

Comme vous pouvez le voir, la possibilité de modifier l'élément de l'itérateur points dépend uniquement de savoir si c'est un iterator ou const_iterator, et la possibilité de modifier l'itérateur lui-même ne dépend que de savoir si la déclaration de la variable pour l'itérateur a un const de qualification.

Edit: je viens de réaliser que c'est une série pour les et il n'est donc pas itérateurs à jouer ici à tous (du moins pas explicitement). x n'est pas un itérateur et est en fait une référence directe à un élément du conteneur. Mais vous avez la bonne idée, il sera déduit pour avoir l' const qualificatif peu importe si on est explicitement écrit.

4voto

Je voudrais offrir un contre-point. En Herb Sutter parler à CppCon 2014 "Retour à l'essentiel! L'essentiel de C++ Moderne de Style" (timestamp 34:50), il montre cet exemple:

void f( const vector<int>& v) {
  vector<int>::iterator i = v.begin();       // error
  vector<int>::const_iterator i = v.begin(); // ok + extra thinking
  auto i = v.begin();                        // ok default

Il fait valoir que, auto tout fonctionne même si vous modifiez le paramètre de la fonction, puisqu'il correctement déduit const ou non-const. Plus loin sur la diapositive 36, il déclare "que Vous devez savoir si votre variable est const/volatiles ou non!" comme raisonnement pour expliquer pourquoi "auto&&" est mauvais pour les variables locales.

Essentiellement, il se résume à une question d'opinion. Certains pensent que le fait d'être explicite est bon pour la lisibilité ou la maintenabilité, mais le contraire pourrait être soutenu: être redondant montre un manque de compréhension (que ce soit du C++ règles ou ce que votre code est en train de faire1) et qui pourraient nuire à la lisibilité et la maintenabilité. Faire ce que vous pensez est le meilleur.

1: C'est plutôt un exemple artificiel, mais le C++de règles de pouce ne fonctionnent pas vraiment dans le cas général, et sont difficiles à mémoriser. Par exemple, Herb Sutter recommande que vous avez les paramètres du constructeur passage par valeur contrairement à la fonction normale des surcharges. C'est l'une de ces situations où l' const partout pourrait vous mordre dans le pied, en fonction de si oui ou non vous êtes d'accord avec l'Herbe.

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