3
votes

Pourquoi std :: string_view n'a-t-il pas les méthodes assign () et clear ()?

L'implémentation de ces méthodes me semble simple et elles rendraient l'utilisation de std :: string et std :: string_view plus interchangeable. Après tout, std :: string_view a des constructeurs qui laissent l'objet dans le même état que ces méthodes. On pourrait contourner les méthodes manquantes comme ceci:

std::string s {"abcd"};
std::string_view v {s.c_str()};
std::cout << "ctor:   " << v << std::endl; // "abcd"
v = {s.c_str() + 1, 2};
std::cout << "assign: " << v << std::endl; // "bc"
v = {nullptr}; // or even v = {};
std::cout << "clear:  " << v << std::endl; // ""

Alors, quelles sont les raisons pour ne pas inclure ces deux méthodes évidentes dans la norme?

MISE À JOUR: Une question générale dans vos commentaires semble être «À quoi ça sert?», Alors je vais vous donner un peu de contexte. J'analyse une grande chaîne avec le résultat étant une structure de sous-chaînes. Cette structure de résultat est un candidat naturel pour les vues de chaînes, donc je n'ai pas à copier toutes ces chaînes, qui se chevauchent même. Une partie du résultat est constituée de mappages vers des vues de chaîne, donc je devrai peut-être les construire vides lorsque j'obtiens la clé et les remplir plus tard lorsque j'obtiens la valeur. Lors de l'analyse, je dois garder une trace des chaînes intermédiaires, ce qui implique de les mettre à jour et de les réinitialiser. Maintenant, ils pourraient également être remplacés par des vues de chaîne, et c'est ainsi que je suis arrivé à ces fonctions manquantes. Bien sûr, je pourrais continuer à utiliser des chaînes ou les remplacer par de vieilles paires ptr-ptr ou ptr-size, mais c'est exactement à cela que sert std :: string_view , non?


7 commentaires

Pour être clair: vous vous attendriez à ce que cela fasse que l'objet "regarde" une chaîne différente (ne modifie pas réellement la chaîne actuellement affichée)?


Oui, il suffit de changer la vue, pas la chaîne sous-jacente.


C'est sémantiquement différent des méthodes std :: string correspondantes (ce qui est probablement la raison pour laquelle vous recherchez). Tout comme le changement d'un pointeur sur un nullptr est différent de la suppression de l'objet pointé.


Afaik, le but principal de string_view est de remplacer const string & dans les paramètres d'une fonction. C'est une bonne question, quel serait le point de string_view :: clear et string_view :: assign.


@MaxLanghof Je pense comprendre ce que vous dites mais je ne suis pas d'accord sur la différence sémantique. Vous effacez une chaîne et vous effacez une vue, après quoi les deux sont vides. Même sémantique. Qu'il y ait ou non une désallocation de la mémoire ou tout ce qui se passe sous le capot n'a pas vraiment d'importance. Sinon, std :: vector :: clear () serait sémantiquement différent de std :: vector :: clear () , non?


@Simpleton Non, cette analogie vectorielle ne tient pas. Vous supprimez (et libérez) tous les éléments. Les deux int et int * sont faciles à désallouer, il n'y a pas de différence sémantique. Pour mémoire, je suis d'accord avec vous qu'il existe des "interprétations" de assign et clear là où il n'y a pas de différence sémantique prononcée. Mais vous devez convenir qu'il est potentiellement difficile de savoir si clear efface également la chaîne visualisée elle-même - après tout, std :: string fait cela.


@MaxLanghof Mon point était que le vecteur possède le pointeur, qu'il désalloue (tout comme les valeurs int), mais pas la pointee, qu'il ne désalloue pas. Vous et moi et tout le monde le sait. Idem avec string_view à mon avis, la pointee ne serait jamais désallouée sur clear (). Pourquoi string_view ferait-il cela, c'est juste une vue sur un objet existant, pas un pointeur intelligent. Pourtant, les gens semblent être d'accord avec vous et s'attendent à ce que cela fonctionne sur la chaîne sous-jacente. Quoi qu'il en soit, votre point est clair, même si je ne suis pas d'accord. Merci pour votre contribution, mais mettons fin à la discussion sur la sémantique.


3 Réponses :


5
votes

L'interface std :: string a une mauvaise réputation en raison de son API soufflée , c'est pourquoi std :: string_view est très peu susceptible d'obtenir autant de méthodes que std :: string simplement parce que c'est pratique ou fait les deux types plus interchangeables.

Mais plus important encore, ces types ne sont pas censés être interchangeables. Que signifie «effacer» la vue sur un conteneur de caractères? Comme clear () est présent sur tous les conteneurs STL et fait quelque chose de significatif, avoir un std :: string_view :: clear () serait assez déroutant.

De plus, une vue sur certaines données est destinée à une consommation temporaire, par ex. un paramètre de fonction en lecture seule. Pourquoi voudriez-vous lui attribuer de toute façon? Voici un exemple de signature de fonction qui utilise std::string_view:

// Called e.g. with "x86_64-Darwin-16.7.0"
std::string_view extractOSName(std::string_view configStr)
{
    // Parse input, return a new view. Lifetime/ownership managed by caller.
    // No need to re-assign anything, let alone "clearing" them.
}


3 commentaires

Je suis d'accord que l'API std :: string est totalement exagérée, mais les fonctions assign () et clear () sont à peu près standard dans toutes les conteneurs. Et std :: string_view agit comme un conteneur dans le sens où peu importe si vous regardez un std :: string_view ou un std: : chaîne const & . C'est ce que je voulais dire par interchangeable. Mais je ne comprends pas ce qui pourrait être déroutant à propos de std :: string_view :: clear () . Que pourrait-il faire d'autre que d'effacer la vue pour qu'elle soit vide par la suite? Personne ne s'attendrait à ce qu'il supprime réellement la chaîne sous-jacente, non?


Vous dites que "cela n'a pas d'importance si vous regardez un std :: string_view ou un std :: string const & ", mais cela n'implique pas que assign n'a aucun sens en premier lieu, car un std :: string const & ne peut pas être modifié? Sur le sujet clear : je pense que les vues sont censées être des objets de courte durée principalement pour les paramètres de fonction. Réinitialiser l'objet qu'ils voient n'est peut-être tout simplement pas le scénario pour lequel ils ont été conçus? Mais ce n'est rien d'autre qu'une supposition.


Je suppose qu'il faudrait faire la distinction entre la construction d'une vue chaîne et son utilisation. La construction n'est peut-être pas aussi simple qu'un simple appel de constructeur, voyez le contexte que j'ai fourni dans ma question. Il existe également des fonctions std :: string_view :: remove_prefix / suffix () , qui ne sont pas const. Mais utiliser un std :: string_view const & devrait être pratiquement impossible à distinguer de l'utilisation d'un std :: string const & , je pense.



1
votes

La mise en œuvre de ces méthodes me semble simple et elles rendraient l'utilisation de std :: string et std :: string_view plus interchangeable.

std :: string_view n'est pas destiné à remplacer std :: string . Il est destiné à remplacer const std :: string & . assign et clear ne sont pas des fonctions membres de const std :: string & que vous pouvez appeler.


1 commentaires

Bon point mais remove_prefix et remove_suffix ne le sont pas non plus



2
votes

Ce ne sera vraiment que de la spéculation, mais le consensus général semble être que ces opérations ne seraient pas assez claires.

Personnellement, je pense que "effacer une vue" est parfaitement logique (et n'oublions pas non plus que remove_prefix et remove_suffix existent! Bien que voir ci-dessous ...), mais je conviennent également qu'il existe d'autres interprétations, qui peuvent être courantes, qui ont moins de sens. Rappelez-vous que string_view est destiné à compléter const std :: string & , pas std :: string , et aucune des fonctions que vous nommez ne fait partie de l'interface constante de std :: string .

Pour être honnête, le fait que nous ayons besoin de cette conversation est, en soi, probablement une bonne raison pour ne pas avoir la fonction en premier lieu.

De le final proposition pour string_view , le passage suivant ne concerne pas spécifiquement assign ou clear mais agit comme une vue pertinente [ lol] dans l'esprit du comité sur ce sujet:

<₹ s / remove_prefix / pop_front /, etc.

Dans Kona 2012, j'ai proposé une classe range<> avec des membres pop_front , etc. qui ajustaient les limites de la plage. La discussion a indiqué que les membres du comité n'étaient pas à l'aise d'utiliser les mêmes noms pour les opérations de tir léger que pour les opérations de conteneurs . La pratique existante ne s'entend pas sur un nom pour cette opération, j'ai donc conservé le nom utilisé par StringPiece de Google.

Cette proposition comprenait en fait un clear () , qui a été rayé sans cérémonie du registre dans une proposition ultérieure, isolée et sans justification .

Maintenant, on pourrait dire que les fonctions auraient donc pu être fournies sous des noms différents, mais cela n'a jamais été proposé, et il est difficile d'imaginer quels noms alternatifs résoudraient ce problème sans être simplement de mauvais noms pour les opérations.

Puisque nous pouvons assez facilement attribuer une nouvelle string_view , y compris une vide, tout le problème est résolu simplement en ne prenant pas la peine de le résoudre.


7 commentaires

Ce sont de bonnes informations sur le remove_prefix et remove_suffix . Cette proposition explique également pourquoi elle existe même si elle n'est pas dans une chaîne (utilitaire, supposément), mais pas pourquoi si elle est ajoutée à la vue, pourquoi ne pas l'ajouter également à la chaîne.


"tout le problème est résolu en ne prenant tout simplement pas la peine de le résoudre." Eh bien, j'étais simplement curieux de savoir pourquoi ne pas inclure ces fonctions. J'espérais que quelqu'un interviendrait avec le passage approprié de la norme au lieu que les gens expriment leur inconfort (pour moi injustifié) avec ces fonctions hypothétiques. Et il est là et que dit-il? Ils les ont omis parce que certains «membres du comité n'étaient pas à l'aise» avec cela. Eh bien ... En voyant la discussion ici, il était probablement justifié ... Marqué comme répondu.


@Simpleton Pour clarifier, c'est le comité qui a résolu le problème en ne l'abordant pas, en n'ajoutant tout simplement pas ces fonctions. C'était une bonne question; Je ne pense tout simplement pas que nous puissions faire mieux que ce qui précède. Il n'y a certainement aucune justification dans le texte normatif ou non normatif à ce sujet.


@LightnessRacesinOrbit, est-ce la proposition finale? Cela semble avoir un clair?


@JeffGarrett Oh, mec, c'est le cas ... (a) quelqu'un m'a menti, et (b) l'intrigue s'épaissit. Je vais devoir y revenir dans la matinée. Bon endroit!


Mais alors: http://www.open -std.org/jtc1/sc22/wg21/docs/papers/2014/n428‌ 8.html Malheureusement sans aucune explication ...


@Simpleton Lol.