4 votes

Pourquoi std::basic_string ne supporte-t-il pas la concaténation à travers les modèles d'expression ?

Qt QString peuvent être concaténés par operator% qui utilise des modèles d'expression pour précalculer la taille de la chaîne résultante et optimiser plusieurs appels enchaînés à operator+ . Voir cette question que je me pose pour plus d'informations.

Pourquoi les std::basic_string a adapté une construction similaire ? Est-ce même autorisé par le C++11 ? Je n'y vois que des avantages et il est clair que la compatibilité ABI peut être rompue par les implémenteurs de bibliothèques lorsqu'ils le souhaitent (et C++11 a fourni une bonne raison même pour libstdc++).

5voto

Nicol Bolas Points 133791

Parce que personne ne l'a proposé pour la norme ; à moins que quelqu'un ne propose quelque chose, cela ne sera pas inclus. Aussi parce qu'il pourrait casser le code existant (s'ils utilisent operator+ c'est-à-dire).

En outre, les modèles d'expression ne fonctionnent pas bien en présence de auto . Faire quelque chose d'aussi simple que auto concat = str1 % str2; peuvent facilement être brisées. Espérons que le C++17 résoudra ce problème d'une manière ou d'une autre.

1voto

Jason Points 20479

En C++11 std::basic_string supporte la sémantique de déplacement, ce qui signifie que vous pouvez optimiser la concaténation d'une série de chaînes de caractères à l'aide de operator+ en allouant de la mémoire pour la première chaîne de la série, puis construit simplement le reste des chaînes dans la mémoire de la première chaîne de la série, ce qui réduit considérablement le nombre d'allocations et de copies de mémoire nécessaires pour concaténer et renvoyer une série de chaînes.

Je suis sûr qu'il y a d'autres optimisations à faire comme vous l'avez souligné avec la méthode de Qt, mais la sémantique de déplacement permise par le C++11 surmonte un énorme obstacle à la performance qui existait dans la version C++03 de std::basic_string surtout lorsqu'il s'agit de concaténer un grand nombre de chaînes de caractères.

Ainsi, par exemple, quelque chose comme

std::string a = std::string("Blah blah") + " Blah Blah " + " Yadda, Yadda";

peut se faire en allouant de la mémoire pour la première chaîne, puis en utilisant la sémantique de déplacement, en "volant" la mémoire restante de la première chaîne pour construire les deux autres chaînes à la place, et en ne réallouant de la mémoire que lorsqu'il n'y a plus d'espace disponible. Enfin, l'opérateur d'affectation peut, en utilisant la sémantique de déplacement, "voler" la mémoire de la valeur r temporaire créée du côté droit de l'opérateur d'affectation, empêchant ainsi une copie de la chaîne concaténée.

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