Quelle est la justification de la parenthèse en C++11 brutes des littéraux de chaîne R“(...)”?
Il y a une fonctionnalité très pratique introduit dans C++11 appelé raw littéraux de chaîne, qui sont des chaînes de caractères avec aucun des caractères d'échappement. Et au lieu d'écrire ceci:
regex mask("\\t[0-9]+\\.[0-9]+\\t\\\\SUB");
Vous pouvez simplement écrire ceci:
regex mask(R"(\t[0-9]+\.[0-9]+\t\\SUB)");
Bien plus lisible. Cependant, la note supplémentaire parenthèse autour de la chaîne-on en place pour définir les raw d'un littéral de chaîne.
Ma question est, pourquoi avons-nous besoin? Pour moi, il semble assez laid et illogique. Voici les inconvénients de ce que je vois:
- Supplémentaire de verbosité, tandis que la fonction est utilisée pour faire des littéraux plus compact
- Difficile de distinguer entre le corps de la littéralité et la définition des symboles
C'est ce que je veux dire par la difficile distinction:
"good old usual string literal"
^- body inside quotes -^
R"(new strange raw string literal)"
^- body inside parenthesis -^
Et voici le pro:
- Plus de souplesse, plus de caractères disponibles dans les premières chaînes, en particulier lorsqu'il est utilisé avec le délimiteur:
"delim( can use "()" here )delim"
Mais bon, si vous avez besoin de plus de flexibilité, vous avez bon vieux escapeable littéraux de chaîne. Pourquoi la norme le comité a décidé de polluer le contenu de chaque raw littéral de chaîne avec ces absolument inutiles entre parenthèses? Quel est le raisonnement derrière cela? Quels sont les avantages que je n'ai pas mentionné?
UPD La réponse par Kerrek est grande, mais ce n'est pas une réponse, malheureusement. Depuis que j'ai déjà décrit ce que je comprends comment il fonctionne et quels sont les avantages donne-t-il. Cinq ans ont passé depuis que j'ai posé cette question, et il n'y a toujours pas de réponse. Et je suis toujours frustré par cette décision. On pourrait dire que c'est une question de goût, mais je ne serais pas d'accord. Combien d'espaces utilisez-vous, comment faites-vous le nom de vos variables, est-ce SomeFunction()
ou some_function()
- c'est la question de goût. Et je peux vraiment facile de passer d'un style à l'autre.
Mais que cette?.. Se sent toujours maladroit et maladroit, après tant d'années. Non, ce n'est pas sur le goût. C'est la façon dont nous voulons couvrir tous les cas possibles n'importe quoi. Nous vouée à l'écriture de ces vilaines parens chaque fois que nous avons besoin d'écrire un Windows chemin d'accès spécifique, ou une expression régulière, ou un multi-ligne de chaîne littérale. Et pour quoi faire?.. Pour les rares cas où nous avons réellement besoin de mettre "
dans une chaîne de caractères? Je voudrais être sur que la réunion du comité de là où ils ont décidé de faire de cette façon. Et je serais fortement contre ce vraiment une mauvaise décision. Je le souhaite. Maintenant, nous sommes condamnés.
Je vous remercie pour la lecture de ce jour. Maintenant, je me sens un peu mieux.
UPD2 Voici mes propositions alternatives, qui je pense pourrait être BEAUCOUP mieux que l'existant.
Proposition 1. Inspiré par python. Ne peut pas soutenir les littéraux de chaîne à triple guillemets: R"""Here is a string literal with any content, except for triple quotes, which you don't actually use that often."""
Proposition 2. Inspiré par le sens commun. Prend en charge tous les possibles littéraux de chaîne, tout comme l'actuel: R"delim"content of string"delim"
. Avec délimiteur vide: R""Looks better, doesn't it?""
. Vide chaîne brute: R""""
. Chaîne brute avec des guillemets doubles: R"#"Here are double quotes: "", thanks"#"
.
Des problèmes avec ces propositions?
R";-](R"(this is a basic raw string literal as text inside a more complex one)");-]"
- La syntaxe est en effet assez laid de l'omi, mais je ne peux pas vraiment penser à une alternative qui peut aussi rester compatible et de garder toutes les fonctionnalités.
- voir la mise à jour de question.
- J'aime la première proposition, il serait peut-travail comme une alternative. Je suppose que c'est un avantage de
R"(...))"
's la laideur sert comme un signe d'avertissement que pour moi, "ceci est une chaîne littérale, être prudent, car il est tellement. - les rares cas où nous avons réellement besoin de mettre des " dans une chaîne de caractères?" Le fait que vous croyez que les cas où vous avez besoin
"
dans une chaîne brute sont "rares" est probablement une partie du problème. Ce n'est pas qu'il n'y a "pas de réponse". Il y a une réponse; vous n'avez tout simplement pas d'accord avec elle. Si votre définition de ce qui constitue une "réponse" est "quelque chose qui m'a convaincu de changer d'avis sur ce", votre question est trop opiniâtre. La justification n'a été fournie; votre accord avec, il n'est pas nécessaire. - Vous ne devez pas mettre à jour un historique très upvoted question d'inclure une nouvelle question " au lieu de poster une nouvelle question. (Qui sera probablement fermé comme l'opinion de toute façon, depuis votre seule objection qui semble être "je trouve cela inesthétique")
- Cette question n'ont pas accepté de répondre à toute façon. Et j'ai mis à jour suite à une logique de demande dans les commentaires.
Vous devez vous connecter pour publier un commentaire.
Que les autres réponse explique, il doit y avoir quelque chose de supplémentaire pour le guillemet pour éviter l'analyse de l'ambiguïté dans les cas où
"
ou)"
, ou en fait tout de clôture de la séquence qui peuvent apparaître dans la chaîne elle-même.Comme pour la syntaxe choix, eh bien, j'accepte la syntaxe choix est sous-optimale, mais c'est OK en général (on pourrait penser qu'elle: "les choses pourraient être pires", lol). Je pense que c'est un bon compromis entre simplicité d'utilisation et l'analyse de la simplicité.
Il y a en effet un problème avec ce - "entre guillemets, que vous n'en utilisent pas souvent".
Tout d'abord, l'idée même de chaînes brutes est de représenter raw cordes, c'est à dire exactement comme ils apparaissent dans un fichier texte, sans tout modifications à la chaîne, quel que soit le contenu de la chaîne. Deuxièmement, la syntaxe doit être générale, c'est à dire sans ajout de variations comme "presque chaîne brute", etc.
Comment voulez-vous écrire un devis avec cette syntaxe? Deux citations? Remarque - ce sont des cas très fréquents, en particulier lorsque votre code est de traiter avec des chaînes et de l'analyse.
Bien, ce pourrait être un meilleur candidat. Une chose si commune au cas (et je crois que c'était une motivation de cas pour la accepté de syntaxe), est que le double-quote personnage lui-même est très commun premières et les chaînes doivent venir dans maniable pour ces cas.
Donc, permet de voir, normal syntaxe de la chaîne:
Votre syntaxe par exemple, avec "x" comme delim:
Accepté de syntaxe:
Oui, je suis d'accord que les crochets introduire quelques ennuyeux effet visuel. Alors je soupçonne les auteurs de la syntaxe été au bout de l'idée que les autres "delim" dans ce cas sera rarement nécessaire, car
)"
ne semble pas très souvent à l'intérieur d'une chaîne. Mais otoh, que, de fuite/leader/isolé citations sont très souvent, si par exemple votre proposition de syntaxe (#2) aurait besoin d'un peudelim
plus souvent, ce qui nécessiterait le plus souvent un changement deR""..""
àR"delim"..."delim"
. J'espère que vous obtenez l'idée.Pourrait la syntaxe de mieux? Personnellement, je préfère encore plus simple variante de la syntaxe:
Avec les exemples ci-dessus:
Cependant à fonctionner correctement (si ses possible dans le courant de la grammaire), cette variante aurait besoin de limiter le jeu de caractères pour le
delim
partie, disent les lettres/chiffres (parce que des opérateurs existants), et peut-être des restrictions supplémentaires pour le caractère initial pour éviter les affrontements avec les futurs possibles de la grammaire.Je crois donc un meilleur choix aurait pu être fait, même si rien n' significativement mieux peut être fait dans ce cas.
L'usage des parenthèses est pour vous permettre de spécifier un séparateur personnalisé:
Dans votre exemple, et en cas d'utilisation typique, le délimiteur est tout simplement vide, de sorte que le raw chaîne de caractères est délimitée par les séquences
R"(
et)"
.Permettant arbitraire délimiteurs est une décision de conception qui reflète le désir de fournir une solution complète, sans étranges limitations ou des cas limites. Vous pouvez choisir tout séquence de caractères qui ne se produit pas dans votre chaîne de caractères comme délimiteur.
Sans cela, on serait dans le pétrin si la chaîne contient quelque chose comme
"
(si vous aviez vouluR"..."
comme de votre première syntaxe de la chaîne) ou)"
(si le délimiteur est vide). Les deux sont parfaitement commun et fréquent des séquences de caractères, en particulier dans les expressions régulières, de sorte qu'il serait incroyablement ennuyeux si la décision si oui ou non vous utilisez une chaîne brute dépendait du contenu de votre chaîne.Rappelez-vous que l'intérieur de la chaîne brute il n'y a pas d'autre mécanisme d'échappement, de sorte que le mieux qu'on pouvait faire autrement a pour concaténer des morceaux de chaîne de caractères littérale, ce qui serait très pratique. En permettant à un séparateur personnalisé, tout ce que vous devez faire est de choisir un caractère inhabituel de la séquence une fois, et peut-être modifier dans de très rares cas, lorsque vous faites une future édition.
Mais de souligner une fois de plus, même le vide séparateur est déjà utile, car les
R"(...)"
syntaxe vous permet de mettre à nu les guillemets dans votre chaîne. Que par lui-même est tout à fait un gain.R"foo(Hello World foo)foo"
)foo
n'apparaît pas dans votre chaîne, y compris la parenthèse. Le d-char-séquence lui-même peut en effet apparaître de façon arbitraire.)"
à l'intérieur de la chaîne est importante pour la compréhension de la possibilité pour d'autres delimter caractères et doit être ajouté à la réponse)foo
peut également apparaître à l'intérieur de la chaîne, mais)foo"
ne peut pas.R"foo(Hello World )foo)foo"
est équivalent à"Hello World )foo"
.