Qu'est-ce que string_view?

162

string_viewétait une fonctionnalité proposée dans le C ++ Library Fundamentals TS ( N3921 ) ajouté à C ++ 17

Autant que je sache, c'est un type qui représente une sorte de "concept" de chaîne qui est une vue de tout type de conteneur qui pourrait stocker quelque chose de visualisable sous forme de chaîne.

  • Est-ce correct ?
  • Le const std::string&type de paramètre canonique doit-il devenir string_view?
  • Y a-t-il un autre point important string_viewà prendre en considération?
Drax
la source
4
Enfin, quelqu'un se rend compte que les chaînes nécessitent une sémantique différente, bien que l'introduction de string_view ne soit qu'une petite étape.
John Z. Li

Réponses:

183

Le but de toutes sortes de propositions de "référence de chaîne" et de "référence de tableau" est d'éviter de copier des données qui sont déjà possédées ailleurs et dont seule une vue non mutante est requise. La string_viewquestion en question est une de ces propositions; il y en avait des plus anciens appelés string_refet array_refaussi.

L'idée est toujours de stocker une paire de pointeur vers le premier élément et la taille d'un tableau ou d'une chaîne de données existant .

Une telle classe de descripteur de vue pourrait être transmise à peu de frais par valeur et offrirait des opérations de sous-chaîne bon marché (qui peuvent être implémentées sous forme de simples incréments de pointeur et d'ajustements de taille).

De nombreuses utilisations de chaînes ne nécessitent pas la possession réelle des chaînes, et la chaîne en question appartiendra souvent déjà à quelqu'un d'autre. Il existe donc un réel potentiel pour augmenter l'efficacité en évitant les copies inutiles (pensez à toutes les allocations et exceptions que vous pouvez enregistrer).

Les chaînes C d'origine souffraient du problème que le terminateur nul faisait partie des API de chaîne, et vous ne pouviez donc pas créer facilement des sous-chaînes sans muter la chaîne sous-jacente (a la strtok). En C ++, cela est facilement résolu en stockant la longueur séparément et en enveloppant le pointeur et la taille dans une seule classe.

Le seul obstacle majeur et divergence par rapport à la philosophie de bibliothèque standard C ++ auquel je peux penser est que ces classes de «vue référentielle» ont une sémantique de propriété complètement différente du reste de la bibliothèque standard. Fondamentalement, tout le reste de la bibliothèque standard est inconditionnellement sûr et correct (s'il compile, c'est correct). Avec des classes de référence comme celle-ci, ce n'est plus vrai. L'exactitude de votre programme dépend du code ambiant qui utilise ces classes. C'est donc plus difficile à vérifier et à enseigner.

Kerrek SB
la source
19
Le navire a navigué sur cette philosophie avec reference_wrapper, n'est-ce pas?
Steve Jessop
5
@KerrekSB J'ai peur de ne pas suivre. Pourriez-vous développer la partie "de telles classes de vues référentielles ont une sémantique de propriété complètement différente du reste de la bibliothèque standard" , s'il vous plaît? Ce n'est pas clair pour moi: en quoi est-ce différent des références / pointeurs suspendus? Ou des itérateurs invalides en raison de l'insertion (par exemple std :: vector)? Nous avons déjà ces problèmes, il est très naturel pour moi qu'une vue non propriétaire ait des problèmes similaires à ceux des pointeurs / références / itérateurs non propriétaires.
Ali
5
@Ali: Lorsque vous utilisez un autre conteneur de bibliothèque standard, vous pouvez affirmer l'exactitude du code simplement en regardant le code qui utilise le conteneur. Pas si pour string_view. (Je ne disais pas que vous ne pouvez jamais écrire de code cassé. Juste que la rupture est locale .)
Kerrek SB
6
Je suis surpris qu'ils ne sont pas venus avec std::rangede boost::iterator_range- l' OMI , il est préférable que l'idée de string_view
Charles Salvia
19
@nwp: De nombreuses personnes et langages en sont venus à déplorer les terribles valeurs par défaut de C ++ et pensent que "const" et "unshared" devraient être la valeur par défaut, avec "mutable" et "shared" les rares exceptions explicites.
Kerrek SB