41 votes

Pourquoi la signature std :: vector :: resize a-t-elle été modifiée en C ++11?

Quelles sont les raisons de la variation en std::vector::resize rapport au pré-C ++11:

 void resize( size_type count, T value = T() );
 

au format compatible C ++11:

 void resize( size_type count );
void resize( size_type count, const value_type& value);
 

47voto

Andy Prowl Points 62121

Le Paragraphe C. 2.12 de l'Annexe C (Compatibilité) pour le C++11 Norme spécifie:

Changement: les changements de Signature rythmique: resize

Justification: les Performances, la compatibilité avec la sémantique de déplacement.

Effet sur la fonction originale: Pour vector, deque, et list de la valeur de remplissage passé pour redimensionner est maintenant adoptée par de référence et non par valeur, et une surcharge de redimensionner a été ajouté. Valide en C++ 2003 code qui utilise cette fonction peut ne pas compiler avec cette Norme Internationale.

Le vieux - resize() fonction était la copie de la construction de nouveaux éléments à partir d' value. Cela rend impossible l'utilisation d' resize() lorsque les éléments du vecteur sont par défaut constructible mais non copiable (vous pouvez déplacer les affecter plus tard). C'est ce qui explique la "Compatibilité avec la sémantique de déplacement" justification.

En outre, il peut être lent si vous ne voulez pas que toute copie de se produire, juste de nouveaux éléments à la valeur par défaut-construit. Aussi, l' value paramètre est passé par valeur en C++03 version, qui engage à la charge d'un inutile copie (comme mentionné par TemplateRex dans sa réponse). C'est ce qui explique la "Performance" de la justification.

17voto

TemplateRex Points 26447

Une des raisons est que les arguments par défaut sont toujours passés, c'est à dire copié dans ce cas. Faire

 my_vector.resize(1000000) 

copie de 1 million T objets.

En C++11 vous avez maintenant le choix entre copier un utilisateur a fourni une valeur par défaut, ou de l'insertion (c'est à dire de la construction), les éléments en place, à l'aide de l' std::allocator_traits<Alloc>::construct() fonction. Cela permet le redimensionnement de l' vector avec des éléments qui sont CopyInsertable mais non Copiable.

Notez que ce changement a été fait pour tous les conteneurs de séquence d'avoir un resize() membre (vector, deque, forward_list et list), mais pas pour std::string qui n'ont pas une valeur par défaut de l'argument pour commencer.

Mise à jour: en dehors de l'Annexe à la Norme actuelle cité par @AndyProwl, l' original du rapport de défaut par @HowardHinnant précise également:

Le problème avec le passage par valeur, c'est qu'il peut être considérablement plus cher que le passage par référence. L'inverse est également vrai, cependant, quand il est vrai, il est habituellement beaucoup moins dramatique (p. ex. pour types scalaires).

Même avec la sémantique de déplacement disponibles, ce passage de paramètre par valeur peut être coûteux. Considérons par exemple le vecteur>:

std::vector<int> x(1000); std::vector<std::vector<int>> v; ...
v.resize(v.size()+1, x); 

Dans le passe-par-cas de valeur, x est une fois copié le paramètre de la redimensionner. Et puis, en interne, étant donné que le code peut ne pas savoir au moment de la compilation par la façon dont beaucoup de redimensionnement est en croissance vecteur, x est généralement copiés (pas déplacé) une deuxième fois à partir de redimensionnement du paramètre dans sa place dans le vecteur.

Avec passe-par-const-référence, le x dans l'exemple ci-dessus doivent être copié qu'une seule fois. Dans ce cas, x est un coûteux constructeur de copie et ainsi de toutes les copies qui peuvent être sauvées représente une économie significative.

Si l'on peut être efficace pour le push_back, nous devrions être efficace pour redimensionner ainsi. La redimensionner en prenant un paramètre de référence a été codé et expédiées dans les CodeWarrior bibliothèque sans rapports de problèmes qui, j'en suis conscient.

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