9
votes

Abuser de l'opérateur des virgules

Je cherche un moyen facile de construire une gamme de chaînes lors de la compilation. Pour un test, je mets ensemble une classe nommée Strings Code> qui possède les membres suivants: xxx pré>

Utilisation de cela, je peux compiler avec succès le code comme celui-ci: p> xxx pré>

le s = "bonjour" code> fait appel de l'opérateur = code> qui renvoie un strings & code> et ensuite le opérateur, code> appelé à "world!" code>. p>

Ce que je ne peux pas avoir au travail (en MSVC, n'ai pas essayé d'autres compilateurs pourtant) est p> xxx pré>

je suppose ici que strings s = "bonjour" code> appellerait le constructeur de copie puis tout se comporterait de la même manière que le premier exemple. Mais je reçois l'erreur: Erreur C2059: Erreur de syntaxe: 'string' code> p>

Cependant, cela fonctionne bien: P>

Strings s="Hello"; 


6 commentaires

Wow, j'ai entendu beaucoup de blagues sur la surcharge de l'opérateur des virgules. Je ne m'attendais jamais à ce que quelqu'un fasse .


@CARL: Qu'en est-il de Boost.org/doc /Libs/1_40_0/libs/Assign/doc/index.html#intro (beaucoup comme quelque chose de voeuté)


frighder mettre des ongles dans votre propre cercueil. Comment allez-vous déboguer cela quand cela commence à se tromper?


@Carl: Vous voulez dire maintenant? :)


Je sais que ce n'est pas une bonne idée de surcharger l'opérateur des virgules. J'essaie juste de faire une API très amicale pour les personnes qui ne connaissent pas beaucoup C ++. J'ai fait valoir la direction sur la façon dont les gens devraient apprendre C ++ et le faire correctement, mais la décision est de rendre une interface sympathique presque scriptable à nos affaires, et c'était une seule idée de la rendre facile pour les gens faire la liste des chaînes (ou vraiment quelque chose si j'en ai besoin)


Pour une interface scriptable, je vous recommande vivement d'utiliser C ++. Vous préférez probablement choisir quelque chose comme Lua ( Lua.org ) qui était conçu à être scriptable et intégré. En descendant le chemin d'essayer de rendre C ++ plus amical conduit à des endroits profonds et sombres.


7 Réponses :


14
votes

Je pense que la virgule dans votre deuxième exemple n'est pas l'opérateur de la virgule, mais plutôt l'élément de grammaire pour plusieurs déclarations variables.

par exemple, de la même manière que vous pouvez écrire: p> xxx pré>

Il me semble que vous écrivez essentiellement: P>

Strings s="Hello", stringliteral


2 commentaires

Au risque d'être fastidieux pédant, s = "bonjour"; est équivalent à Strings S = cordes ("Bonjour"); . Il nécessite que la copie CTOR soit appelable et peut même l'appeler, construire s à partir d'un objet temporaire. Mais l'optimisation pour la remplacer par une initialisation directe à l'aide du constructeur constR * constructeur pour s , sans aucune temporaire, est autorisé et commun.


Duh, je ne peux pas croire que je n'ai pas vu celui-là.



5
votes

0 commentaires

8
votes

Je ne recommanderais pas ce genre d'API. Vous allez continuer à découvrir des cas qui ne fonctionnent pas comme prévu, car la virgule est l'opérateur avec la priorité la plus basse. Par exemple, ce cas ne fonctionnera pas non plus:

if (("Hello","world") == otherStrings) { ... }


2 commentaires

Cela peut-il être fait pour fonctionner? Le problème que je prévois est que vous ne pouvez pas surcharger opérateur, pour const char * , donc ("bonjour", "monde") est juste la même chose que "monde" .


J'ai supposé que vous pouvez surcharger l'opérateur, (Cons-Char *, Const Char *). Y a-t-il une raison pour laquelle cela ne peut pas être fait? Je ne fais pas beaucoup de programmation C ++, d'être honnête.



0
votes

Vous pouvez utiliser un tableau de pointeurs de caractères xxx

et à l'intérieur du constructeur, itérale à travers les pointeurs jusqu'à ce que vous atteigniez la null.


2 commentaires

Ou modèle le constructeur: modèle chaînes (const caractère * (et entrée) [n]) {pour (int i = 0; i . Ensuite, aucun terminateur null n'est requis: vous pouvez faire const char * entrée [] = {"this", "ça"}; Strings s (entrée); . Pas sûr que ça vaut vraiment la peine, mais amusant si vous aimez ce genre de chose.


Oh, ou bien sûr, le modèle de constructeur pourrait appeler une autre fonction similaire à Vector :: Insérer (Itérateur, INTTÉTRAATOR, INTÉTRATEUTORATOR) , pour éviter le code dupliqué étant généré si vous l'appelez avec beaucoup de longueurs différentes de différentes longueurs. des endroits.




0
votes

Si le seul travail de Strings est de stocker une liste des chaînes, alors boost :: Attribuer pourrait mieux faire le travail avec des conteneurs standard, je pense :) < Pré> xxx


0 commentaires

1
votes

Il est possible de faire ce travail, pour une définition suffisamment lâche du "travail". Voici un exemple de travail que j'ai écrit en réponse à une question similaire il y a quelques années. C'était amusant comme un défi, mais je ne l'utiliserais pas en code réel: xxx


0 commentaires